なたで日記

いろいろな思ったこと書きますヽ(^▽^ゞ) by natade

Archive for the ‘program’ Category

セカンドライフで自分の行動の色々な情報を取得する

leave a comment »


次のような自分の行動の情報を取得してみます。
・自分が喋った回数
・人から聞いた回数(アバターが話したものに限定)
・空を飛んでいる時間(ホバーは含めない)
・海の中を泳いでいる時間(ホバーは含めない)
・歩いている時間
・走った時間
・ジャンプ中の時間
・テレポートした回数
・SIMをまたいだ回数
・人や当たり判定がある物体と衝突した回数

以下、サンプルです。
このコードを適当なオブジェクトに入れた後、HUDとして装備してください。
drawStatusと発言すると、自分の情報が表示されます。

ログインした回数とかも取れるかなと思ったのですが、
装備した回数と見分けがつかないので諦めました。

integer count_attack		= 0;
integer count_speak			= 0;
integer count_listen		= 0;
integer count_flying		= 0;
integer count_swimming		= 0;
integer count_running		= 0;
integer count_walking		= 0;
integer count_teleport		= 0;
integer count_simtraversal	= 0;
integer count_jumping		= 0;

integer TYPE_ATTACK			= 0;
integer TYPE_SPEAK			= 1;
integer TYPE_LISTEN			= 2;
integer TYPE_FLYING			= 3;
integer TYPE_SWIMMING 		= 4;
integer TYPE_RUNNING		= 5;
integer TYPE_WALKING		= 6;
integer TYPE_TELEPORT		= 7;
integer TYPE_SIMTRAVERSAL	= 8;
integer TYPE_JUMPING		= 9;

integer show_dialog		= FALSE;
integer listen_handle	= -1;

addAction(integer action) {
//	llOwnerSay("action : "+ (string)action);
	if(action == TYPE_ATTACK) {
		count_attack	= count_attack + 1;
	}
	else if(action == TYPE_SPEAK) {
		count_speak		= count_speak + 1;
	}
	else if(action == TYPE_LISTEN) {
		count_listen	= count_listen + 1;
	}
	else if(action == TYPE_FLYING) {
		count_flying	= count_flying + 1;
	}
	else if(action == TYPE_SWIMMING) {
		count_swimming	= count_swimming + 1;
	}
	else if(action == TYPE_RUNNING) {
		count_running	= count_running + 1;
	}
	else if(action == TYPE_WALKING) {
		count_walking	= count_walking + 1;
	}
	else if(action == TYPE_TELEPORT) {
		count_teleport	= count_teleport + 1;
	}
	else if(action == TYPE_SIMTRAVERSAL) {
		count_simtraversal	= count_simtraversal + 1;
	}
	else if(action == TYPE_JUMPING) {
		count_jumping	= count_jumping + 1;
	}
}

showStatus() {
	llWhisper(0,
		"attack\t:"			+ (string) count_attack			+ " times\n" +
		"speak\t:"			+ (string) count_speak			+ " times\n" +
		"listen\t:"			+ (string) count_listen			+ " times\n" +
		"teleport\t:"		+ (string) count_teleport		+ " times\n" +
		"simtraversal\t:"	+ (string) count_simtraversal	+ " times\n" +
		"flying\t\t:"		+ (string) count_flying			+ " sec\n" +
		"swimming\t\t:"		+ (string) count_swimming		+ " sec\n" +
		"running\t:"		+ (string) count_running		+ " sec\n" +
		"walking\t:"		+ (string) count_walking		+ " sec\n" +
		"jumping\t:"		+ (string) count_jumping		+ " sec"
	);
}

openDialog() {
	if(listen_handle != -1) {
		llListenRemove(listen_handle);
	}
	listen_handle = llListen(-100, "", llGetOwner(), "");
	llDialog( llGetOwner(), "Which operation?\nYou say \"drawStatus\"... or \"resetStatus\"", ["status", "reset", "cancel"], -100 );
	llSetTimerEvent(0.0);
	llSetTimerEvent(30.0);
	show_dialog = TRUE;
}

closeDialog() {
	if(listen_handle != -1) {
		llListenRemove(listen_handle);
	}
	show_dialog = FALSE;
	listen_handle = llListen(0, "", "", "");
	llSetTimerEvent(0.0);
	llSetTimerEvent(1.0);
}

default {
	state_entry() {
		llOwnerSay("Start Script !\nYou say \"drawStatus\"... or \"resetStatus\"");
		closeDialog();
	}
	
	touch_start(integer total_number) {
		openDialog();
	}
	
	timer() {
		if(show_dialog) {
			closeDialog();
		}
		else {
			string my_animatin = llGetAnimation(llGetOwner());
			if(my_animatin == "Flying") {
				vector v = llGetPos();
				if(llWater(v) > v.z) {
					addAction(TYPE_SWIMMING);
				}
				else {
					addAction(TYPE_FLYING);
				}
			}
			else if(my_animatin == "Running") {
				addAction(TYPE_RUNNING);
			}
			else if(my_animatin == "Walking") {
				addAction(TYPE_WALKING);
			}
			else if(my_animatin == "Jumping") {
				addAction(TYPE_JUMPING);
			}
		}
	}
	
	listen( integer channel, string name, key id, string message ) {
//		llOwnerSay(""+ (string)channel +" " + name + " " + (string)id + " " + message);
		if(show_dialog) {
			if(message == "status") {
				showStatus();
			}
			else if(message == "reset") {
				llResetScript();
			}
			else if(message == "cancel") {
			}
			closeDialog();
		}
		else {
			if(id == llGetOwner()) {
				if(message == "drawStatus") {
					showStatus();
				}
				else if(message == "resetStatus") {
					llResetScript();
				}
				else {
					addAction(TYPE_SPEAK);
				}
			}
			else if(llGetAgentSize(id)){
				addAction(TYPE_LISTEN);
			}
		}
	}
	
	changed(integer mask) {
		if(mask & CHANGED_OWNER) {
			llResetScript();
		}
		if((mask & CHANGED_TELEPORT) && (mask & CHANGED_REGION)) {
			addAction(TYPE_TELEPORT);
		}
		else if(mask & CHANGED_TELEPORT) {
			addAction(TYPE_TELEPORT);
		}
		else if(mask & CHANGED_REGION) {
			addAction(TYPE_SIMTRAVERSAL);
		}
	}
	
	collision_start(integer num) {
		if(llDetectedType(0) & ACTIVE) {
			vector my_velocity = llGetVel();
			vector velocity = llDetectedVel(0);
			float power = llVecMag(my_velocity - velocity);
			if(power >= 1.0) {
				addAction(TYPE_ATTACK);
			}
		}
	}
	
	on_rez(integer param) {
		// 1 ログイン、装備、rez
	}
	
	attach(key attached) {
		if(attached) {
			// 2 ログイン、装備
		}
	}
}

Written by なたで

2017年1月15日 at 00:00

カテゴリー: memo, program

Tagged with ,

セカンドライフのプリムの当たり判定の検証

with one comment


こんにちは!

昨日から引き続き、「セカンドライフ技術系 Advent Calendar 2016」です!

すみません。
昨日の記事は、役に立つ情報もあったかもしれませんが、
今回は、テクニック系と違い、前々から気になっていたことを検証する……といった内容となります。
なんかすごいの来る!と期待していた方はスミマセン。(いないと思われますが)

というわけで、

あんまり面白いものではないかもしれませんが、
調査結果の報告というわけで、話していきます……。


はじめに

昨年に、当たり判定の記事を書きました。
セカンドライフでメッシュに物理形状を設定しよう1

今回は、その記事のさらに「実像の種類」について気になったことを確認していきたいと思います。
最初に少し解説しますが、より理解を深めたい方は前回の記事から読むことをお勧めします。

「実像の種類」というのはオブジェクトの設定から選べるものです。
実像というのは、当たり判定用に用いるオブジェクトです。

gui_jituzo_1 → gui_jituzo_2

ここで実像を「なし」「プリム」「凸状の外殻構造」の3種類選べます。
「なし」にした場合は、当たり判定用のオブジェクトを用意しないということになります。

ここで「プリム」「凸状の外殻構造」の違いについて説明するために、
3次元だと書きにくいので、2次元で考えたいと思います。

atari_hazimeni_1
2枚の壁が90度の垂直であることとします。

atari_hazimeni_2
実像の種類を「凸状の外殻構造」にすると、
黄色の囲んだ部分のように当たり判定が生まれます。
※中身すべてにすべて当たり判定を持つことになります。

atari_hazimeni_3
実像の種類を「プリム」にすると、
そのプリムそのものが1枚の壁のように当たり判定を持ちます。
※中身というものは存在しません。


実像の種類「プリム」の疑問

ここで、私の中では素朴な疑問が生まれました。
当たり判定の計算方法により、アバターが透けることがないのかということです。

たまーに、なぜかよくわからないですが、壁の中に入って閉じ込められることありませんか。
それが、このこの設定によるものなのかなーと、疑問に思ったわけです。

セカンドライフの実際の当たり判定のアルゴリズムについては知らないので少し、推測した話となります。
まず、当たり判定といえば、レイと3角ポリゴンとの衝突の検出※が有名です。
そこで、これをまず使用していると仮定します。
(※アルゴリズム、計算方法については、「はじめての3Dゲーム開発」)

そして、もしこのようなアルゴリズムを使って単純に実装している場合、
つまり、1本のレイを飛ばすような当たり判定を使っているのであれば、
次のような現象が起きるのでは……と思いつきます。

atari_nazo_1
壁1と壁2が90度で交わっているとします。

atari_nazo_2
ここで Ray1 を飛ばします。
つまりアバターが壁1に向かって斜めに突進した感じです。

atari_nazo_3
Ray1は、壁1と壁2の2種類に当たり判定チェックを行います。
その結果、壁1との衝突を検知することができます。
そして、めり込まないように、斜めの成分だけを抜き出します。

atari_nazo_4
次に、壁1との衝突点からRay2を飛ばします。
ここで、問題なのですが、Ray2が壁2との当たり判定を正しく行えるかという謎です。

普通は壁1と壁2は接続されているはずなので、
Ray2は壁2と衝突するはずですが、
実際は壁1と壁2は、別のポリゴンとして管理しており、
これらのポリゴンの位置は、実数による誤差の関係上、微妙に隙間が空いているはずなのです。

1本のレイを使用した単純な当たり判定ならば、上記のような問題は起きるのですが、
もちろん、レイを複数とばす。あるいは、そもそも球とポリゴンとの当たり判定を使用するなど
いろいろな工夫を行っていれば、このようなことになりません。
なので、有名なセカンドライフであれば、すり抜けることはおそらくないはずですが。

というわけで、前置きがすごく長くはありましたが、
当たり判定用のプリム=壁のプリムを作成して、
衝突した場合どうなるか検証するのが、この記事の目的となります!


すり抜けの検証

次のような壁(1辺が10m)を作成して、
atari_test_1

下記のように10分間壁に向かって当たり続けて、すりぬけるか確認します。
atari_test2

ビューアは2種類で確認しました。
公式ビューア(v4.1.2.321518)
Catznipビューア(R10.0)の両方で確認しました。

元となるメッシュデータについては、頂点を共有しないメッシュと、
共有するメッシュの2種類について確認。

また、当たり判定のデータは、dae情報で直接設定する方法と、
表示用メッシュから自動生成する方法の2種類を試しました。

それで早速、結果なのですが、

.
..

なんと

.
..

なんとッ!

.
..

すり抜けませんでした!

まあ、そうですよねー。
期待していた方?はスミマセンでした。

ちなみにさらに検証していったのですが、
隙間がわずかにあってもすり抜けませんでした。

どの程度の隙間からすり抜けるようになるのか気になる点ではありますが、
まずは、接続された面であれば、当たり判定を「プリム」にしていても
問題ないということは確実ということが分かり、安心しました。

たまーにすり抜けるのは、
たぶん、幽霊の仕業か本当に実像的にスキマがあるのでしょう。きっと……


一応、これで2日間にわたる記事は終わりです。
ですが!まだまだ12月が始まったばかりです!

ではみなさま!
セカンドライフ技術系 Advent Calendar 2016」を楽しんでいきましょう!

.
..

.
..

.
..

オマケ

私は、Advent Calendar以外にも普段気が向いたときに、セカンドライフ系の記事をかいております。
その中で、私としてヨイデキな記事をいくつか紹介します。(宣伝デス)

2016年4月21日 セカンドライフのスカイボックスに太陽の光を!
シンプルながらも、知っておくと良いテクニック!

2014年12月29日 セカンドライフの関数逆引きメモ
セカンドライフにはどういった機能があるのか、逆引きをみて一通り覚えておこう!

2014年12月12日 セカンドライフでアニメーション
セカンドライフでアニメーションを作る方法!

Written by なたで

2016年12月2日 at 00:00

カテゴリー: 3D, memo, program

Tagged with , ,

セカンドライフのオブジェクトとの衝突音

leave a comment »


みなさん。お久しぶりです。

ついに今年も「Advent Calendar」の季節がやってきました!

イエーイ!

このようなイベントを開催していただいて、sabro様ありがとうございます!

私は去年から初参戦しているのですが、今年はナント1日目を予約してしまいました。
こんな私が1日目をとってしまってよかったのだろうか……といろいろありますが、
気にせずドンドン始めていきたいと思います!


衝突音

今回のテーマは、音関係の話、具体的には衝突音の話をしたいと思います。

みなさん、衝突音って気にしたことありますか……?

……

あんまり、気にしていない人多いかも。
でも、私はたまーに気になったりします。

例えばですが、プリムで階段を作ったとします。
kaidan

 

こういう階段にダッシュして登ってみましょう!

ゴツッ!

ほら!衝突音しましたよね。

なんとなくどんくさい感じがします。
他にも、柔らかなそうなソファーとかぶつかった時も、
ゴツッ!とか出るのも何だか不自然な感じがします。

実は、このような衝突音、簡単に消せるんです! \テテーン!/

プリムを選択して、スクリプトを追加。

gui_script_1 → gui_script_2
スクリプトでは次のように llCollisionSound で衝突音の設定をします。

default
{
	state_entry()
	{
		llCollisionSound("", 0.0);
	}
}

さあ、これで保存して、同じように階段を上ってみましょう!
衝突音がないため、スムーズに駆け上っている感じがでましたね。


簡単に衝突音設定しよう!

スクリプト面倒という方もいらっしゃると思います。
無音にする方法でなければ、実は手軽に衝突音を変えられるってご存知でしょうか?

具体的には、「オブジェクトの特徴」の設定で、
実像のタイプを選択することができます。

gui_sound_1 → gui_sound_2

デフォルトは「木」となっているのですが、
他にも、いくつか選べて、全部で7種類を選ぶことができます。
それぞれの設定の音は、次のようになります。

  • 石   … 低いゴツ!
  • 金属  … カン!(グレーチングを踏んだような音)
  • ガラス … カン!(氷をアイスピックでたたいたような音)
  • 木   … ゴツ!
  • 肌   … コツ!
  • プラスチック … ドン!
  • ゴム  … コツ!(硬くゴムを机に落としたような音)

※音の印象は個人差があります。

音は用意するの面倒だけど、衝突音を変えたいという方は
ここでGUI上でポチポチ触って変更することをオススメします!


他の音はないの?

先ほどは、簡単に音を設定する方法説明しましたが、
コツ、ゴツ系のみで種類がすくない~(><)と思う方もいると思います。

ただ llCollisionSound を使うにしても、
音を用意するのって結構面倒ですよね。

というわけで、
少し早いですがクリスマスプレゼント!
自由に使える音素材を収録して用意しました!

許可なしで有料/無料問わず自由に使える音のUUIDを公開します。
衝突音以外に使用してもらってもかまいません。

下記のスクリプトを入れれば、衝突音が変わります。
「1.0」と書いてある部分を小さな値にすれば、衝突音の音量を小さくもできます。

床1 … ドン!(低く、重たい音)

default{state_entry(){llCollisionSound("56fa194a-b894-043a-c1fe-04ab0ead663e", 1.0);}}

床2 … ドン!(普通の音1)

default{state_entry(){llCollisionSound("aab46478-b006-6fdb-1c2c-ac04dfa4c1ca", 1.0);}}

床3 … ドン!(普通の音2)

default{state_entry(){llCollisionSound("52dd9553-5c75-6fc8-5573-32df7b56d14d", 1.0);}}

床4 … ドン!(軽く、すこし硬い音)

default{state_entry(){llCollisionSound("88c0cae6-3c0d-6b6c-edee-85a3f1237828", 1.0);}}

アルミホイル … グシャ!

default{state_entry(){llCollisionSound("801f106b-d391-0214-cdd1-709b072b46aa", 1.0);}}

ビニール … グシャ!

default{state_entry(){llCollisionSound("e40d1ca7-d37f-1332-2513-37a8e209dbc6", 1.0);}}

金属音1 … コンッ!(すこし鈍い音)

default{state_entry(){llCollisionSound("b55200e1-b1bc-5302-ada4-ed559671225c", 1.0);}}

金属音2 … カッ!(軽い音)

default{state_entry(){llCollisionSound("739756e2-a4e1-7ab0-879e-118c458e545d", 1.0);}}

布1 … 軽く触れる音

default{state_entry(){llCollisionSound("a7451a80-e9f5-315a-92b2-f96253578077", 1.0);}}

布2 … バサ!

default{state_entry(){llCollisionSound("d64718b2-5923-ff14-c6d5-0ed9dda9d7c4", 1.0);}}

液体1 … ピトッ!

default{state_entry(){llCollisionSound("3bb0d4fc-d738-d04c-22f1-cd35ede613a4", 1.0);}}

液体2 … ペトッ!

default{state_entry(){llCollisionSound("75374bdf-c059-d568-bfe1-093cef58a0fd", 1.0);}}

というわけで、音の話……主に衝突音の話を終わります!

ありがとうございました!

イベントがあると、色々な人に知識を共有出来たり、
自分もさらに調べていこうと啓発もできて、とてもいいものです!
このような場を設けていただき、改めてありがとうございました!

Written by なたで

2016年12月1日 at 00:00

カテゴリー: memo, program

Tagged with ,

Raspberry Pi はじめました (第5回) – DDNS編

leave a comment »


Raspberry Pi はじめました (第4回) – はじめから の続きです。


8. フォルダでアクセスできるようにしよう
8-1. やっぱりWindowsPC上からアクセスしてファイル編集したい
8-2. そこで、これも以前にあったように、sambaをインストール

sudo apt-get install samba

8-3. 設定ファイルを編集

sudo nano /etc/samba/smb.conf

8-4. 次を追加

[pi]
path = /home/pi
read only = No
guest ok = No
force user = pi
browseable = Yes

8-5. 【任意】パスワードを設定

sudo pdbedit -a pi

8-5. サービスの再起動

sudo service samba-ad-dc restart

●●●
9. 外からアクセスできるようにするために、ドメインを作ろう
9-1. ドメインは無料で作ることもできるのですが、安いので買ったほうがいいです。
9-2. ダイナミックDNSが使える会社のがいいです。自サーバーのIPアドレスが固定じゃなくてもよいためです。
9-3. というわけで、VALUE-DOMAIN を使用しましょう。
9-4. 「お名前.com」は、「お名前.comでドメイン取得時にWhois情報公開代行を忘れると大損」なので注意
9-5. 上位レジストラは、eNomだと「ネームサーバーが不正に変更される問題について」らしいので、GMOが安心
9-6. VALUE-DOMAINで登録を終えたら「ダイナミックDNSの設定」で、パスワードを設定する。
9-8. ダイナミックDNS機能を「無効」から「有効」にする
9-9. 「ネームサーバーの設定」→「当サービス内のネームサーバー(ns1~5.value-domain.com)を利用する」
9-10. 「DNS情報/URL転送の設定」で、「a * 1.1.1.1」と設定。アドレスは自分のアドレスとする。
9-11. これで、ダイナミックDNSが使用可能となります。
9-12. 次のURLを入力すると、0と返り、遠隔でIPアドレスを再設定できます。

https://dyn.value-domain.com/cgi-bin/dyn.fcg?d=hoge.com&p=password&h=*

●●●
10. crontabを使ってみよう
10-1. 「\\RASPBERRYPI\pi\CronJobs」というフォルダを作る
10-2. 「startup.sh」というファイルを作る
10-3. 中身は下記のようにする

#!/bin/sh
# ここにスクリプトを書いていく
exit 0

10-4. 実行権限をつける

chmod +x /home/pi/CronJobs/startup.sh

10-5. ルート権限用のcrontabを開く

sudo crontab -e

10-6. 次を追加する

@reboot su - pi -c "/home/pi/CronJobs/startup.sh"

10-7. これで起動時に実行されるスクリプトを登録できました。

sudo timedatectl set-timezone Asia/Tokyo

とかを登録しておくと、日本の日本標準時間になるのでお勧めです。

10-8. 他にも、同様の操作でDDNSの設定を定期的に実行とかも作れます。
10-9. 例えば、 VALUE-DOMAINの場合は、次のような「ddns.sh」を作成して実行権限つけて

#!/bin/sh

domain="hoge.com" 
pass="pass"
path="https://dyn.value-domain.com/cgi-bin/dyn.fcg?h=*&d=${domain}&p=${pass}"

curl -s ${path} >> /dev/null

exit 0

10-10. あとは、これをcrontabに追加すればでよいはず。未確認ですが。

*/30 * * * * su - pi -c  "/home/pi/CronJobs/ddns.sh"

●●●
今日はここまで!
とりあえず、これで外から自宅サーバーへアクセスできるようになります。

Written by なたで

2016年9月19日 at 23:39

カテゴリー: memo, program

Tagged with

Raspberry Pi はじめました (第4回) – はじめから

leave a comment »


今まで
Raspberry Pi はじめました (第1回)
Raspberry Pi はじめました (第2回) – Arduino 用スターターキットを買って分かったこと
Raspberry Pi はじめました (第3回) – ハンダ付けしたい

とラズパイ回、あったのですが、最近してなかったので久しぶりのラズパイ回です。

久しぶりすぎたので、仕切り直したいと思いますー。
というわけで、またラズパイ環境づくりから。


1. マイクロSDカードの準備
1-1. 新品を買ってきてもいいのですが、使っていないマイクロSDカードも利用できます。
1-2. 使っていないマイクロSDカードは、Win32 Disk Imager を使用してまるごとバックアップが楽です。
1-3. 推奨フォーマッターであるSD Card Formatter 4.0を起動。
1-4. 設定は「消去設定:クイックフォーマット、論理サイズ調整:ON」(FAT32でフォーマットされる。)
●●●
2. OSの準備
2-1. Raspberry Pi Downloads – Software for the Raspberry Pi へ行く
2-2. NOOBS を選択。
2-3. Download NOOBS for Raspberry Pi ページにつく
2-4. ダウンロード
2-5. マイクロSDカードの中に、NOOBSの圧縮ファイル(NOOBS_vX_X_X.zip)の中身を全て入れる。
●●●
3. Raspberry Piの起動
3-1. マイクロSDカード、マウス、キーボード、HDMIケーブル、LANケーブルを接続する
3-2. AC電源からUSB電源を作って、Raspberry Pi へ電源供給する。
3-3. Raspbianを選択し、下のメニューで日本を選択してインストールを押す
3-4. 再起動後に、OSが自動起動します
●●●
4. teraterm の準備
4-1. Tera Termをインストール
4-2. 端末の設定は、送受信を「UTF-8」、改行コードを「CR」にする
4-3. フォントの設定を日本語対応の物にして、文字セットを「日本語」にする
4-4. 設定の保存で、TERATERM.INIを上書きしておくと文字化けしない
●●●
5. SSHでログイン
5-1. SSHは最初から有効になっているので、Raspberry PI 上でターミナルを開き、ifconfigでIPアドレスを確認
5-2. Windowsでteraterm を開き、IPアドレスを指定する。
5-3. ユーザー名はpi、パスワードはraspberryでログインする。

ここで、よく使うコマンドをおさらいしておきましょう

コマンド名 意味
pwd 現在のローカルディレクトリを取得
cd ディレクトリを移動
ls ファイル、フォルダの一覧表示
cp ファイル、フォルダのコピー
mv ファイル、フォルダの移動
rm ファイル、フォルダの削除
mkdir フォルダの作成
chmod ファイル、フォルダの権限変更
cat テキストファイルを表示する
nano ナノエディタ
touch 空のファイルを作成
file ファイルの種類を調査
tail ファイルの末尾を表示
grep 指定した文字がある行だけを表示
history 入力したコマンドの履歴
ps 実行しているプロセスを表示
kill 実行しているプロセスをプロセスIDで終了
killall 実行しているプロセスをプロセス名で終了
man コマンドの使い方を表示
sudo reboot 再起動
sudo shutdown -h now シャットダウン
exit sshの終了
tar xf XXX XXXを展開する

●●●
6. 固定IPアドレスの設定
6-1. 今後、SSHで操作するために固定IPアドレスにしておきます。
6-2. これで設定ファイルを開きます(最新のOSだと /etc/network/interfaces ではないので注意)

sudo nano /etc/dhcpcd.conf

6-3. 「192.168.11.200」にしたい場合は、次の行を最後につけたして上書き

interface eth0
static ip_address=192.168.11.200/24
static routers=192.168.11.1
static domain_name_servers=8.8.8.8

6-4. 再起動しましょう

reboot

●●●
7. 【任意】OS上で日本語表示や入力に対応する
7-1. 全てSSHで行うので必要はないのですが、一応メモとして次のような方法があります。
7-2. ネット接続環境で下記を入力すると、日本語フォントとIMEがインストールされます。

sudo apt-get install ttf-kochi-gothic xfonts-intl-japanese xfonts-intl-japanese-big xfont-kaname
sudo apt-get install fonts-vlgothic
sudo apt-get install ibus-mozc

●●●
今日はここまで!
ここまでで、アドレスは固定になったので、
ルーターの近くにおいて常時起動しておきましょう。

Written by なたで

2016年9月17日 at 22:30

カテゴリー: memo, program

Tagged with

セカンドライフのスクリプトのエラー処理について

leave a comment »


セカンドライフでは、スクリプトでエラーが起きるとどうなるかみなさん知っていますか。
何かエラーが出ること自体は知っていると思いますが、
そのエラーが発生後、どうなるのかはそんなに知らないと思います。

ためしに、次のようなスクリプトを実行してみましょう。

hoge() {
	integer x = 0;
	llOwnerSay("hoge_start");
	x = 1 / 0;
	llOwnerSay("hoge_end");
}

default {
	state_entry() {
		llSetTimerEvent(3.0);
	}
	
	touch_start(integer total_number) {
		llOwnerSay("touch_start");
		hoge();
		llOwnerSay("touch_end");
	}
	
	timer() {
		llOwnerSay("clock");
	}
}

このスクリプトは、3秒に1度、発言が行われて、
また、クリックすると0の割り算エラーを発生させるスクリプトです。

これでクリックするとどうなると思いますか。三択問題です。

A. hoge関数内でエラーが発生するので、例外で終了するため”hoge_end”は表示されずに、関数を抜ける
B. touch_startイベント関数内でエラーが発生するので、そこでtouch_startイベント関数が強制終了する
C. プログラム自体が強制終了し、タイマーイベントなど全てが止まる

さて、どうなるでしょう。

正解は・・・


 

 

テテテテテテテ

 

 

ジャン!

Cでした!

なんと、すべて止まってしまうのです。
無限ループもタイマーもすべて止まってしまうので、手動リセットさせるしかありません。
なお、エラーの種類は「LSL Errors」でまとまっていますので、一度見ておくといいかもしれません。
注意点として、メモリリークの「Script run-time error: Stack-Heap Collision」なのですが、
これも発生してしまうと、プログラムが止まってしまいます。
そこで、止まるよりはみずから llGetFreeMemory で定期チェックをして、
llResetScript でリセットさせたほうが安全です。


オマケ

次のスクリプトはエラーが発生するでしょうか……

default {
	state_entry() {
		llOwnerSay((string)((integer)"ABC"));
		llOwnerSay((string)((integer)"123ABC456"));
		llOwnerSay((string)((vector)"ABC"));
		llOwnerSay((string)((vector)"<1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0>"));
	}
}


正解はこんな感じでエラーは発生しません。
文字列の左からデータとして認識できる範囲で変換してくれるようですね。

Object: 0
Object: 123
Object: <0.00000, 0.00000, 0.00000>
Object: <1.00000, 2.00000, 3.00000>

Written by なたで

2016年5月8日 at 21:06

カテゴリー: memo, program

Tagged with ,

Raspberry Pi はじめました (第1回)

leave a comment »


Raspberry Pi が2015年12月22日に届き、いじったメモを書いていきます。
文字中心です……。ごめんなさい。
→最近、また1から環境を整え始めたので、その時のブログは「Raspberry Pi はじめました (第4回)」を参照

購入ものリストです。
Raspberry Pi Model B+
Raspberry Pi Model B+ / Pi 2 Model B 専用ケース(Clear)
Toshiba microSDHC UHS-I Class10 (32GB, 40MB/s)
PLANEX 無線LAN子機 11n/g/b GW-USNANO2A
Arduinoをはじめよう 互換キット 20 in 1 (おすすめしません……詳細は後述)

2015年当時は、ラズパイ2が最新でしたが、2016年9月はラズパイ3が発売しているので、そちらをおすすめします。
なお、ラズパイ3は、2Aの電流が必要でして、それ用のアダプタを購入する必要があります。

上から順番に解説していきます。

2015年12月現在、アマゾンで買えるものは、PiA、PiB+、Pi2B
PiA と PiB+ は、同値段価格で、PiA は消費電力が低くしたい場合に有利です。
Pi2B は、1500円ほど高いですが、CPUやクロック数、コア数が格段にアップしています。
Pi2B がおすすめです。この理由は、飽きても性能がいいため別のことが行えるからです。
(私は間違えて、PiB+を買ってしました・・・。)
ケースは、基盤についているポートが出ていて、熱を逃がしやすいのにしました。
SDカードは安心の東芝製です。
無線LAN子機は付けておいた方がいいので、 GW-USNANO2Aを選びました。
GW-USNANO2A はラズベリ界で有名なようで電力がバッファローのより少ないようです。
もちろんラズベリに刺しただけで認識して、ドライバのインストールは必要ありません。
「Arduinoをはじめよう 互換キット 20 in 1」これは、今回の目的が電子工作なので買いました。
本当は、ラズベリ用のスターターキットも売っているのですが、
上記のArduino用の方がコスパがよさそうなので選択。

ただ、あとで分かったのですが、ラズベリにはAD変換のポートがありません。
AD変換のポートがないと、可変抵抗の値(明度とか)などのアナログ値が直接取得できません。
従って、ラズベリでアナログ値を取得するためには、AD変換のICが必要となります
Arduinoは、AD変換のポートがあるため、このスターターキットにはICがついていないのです。
そこで、ICは秋月電子で、12ビット8ch ADコンバータ MCP3208を購入。
あと、一応他の候補としては、ADS1015搭載 12BitADC 4CH 可変ゲインアンプ付きがあります。
こちらを付ける場合は、I2C通信をする必要があります。

また、「Arduinoをはじめよう 互換キット 20 in 1」に液晶ディスプレイがついてくるのですが、
いろいろ挑戦してみたものの、使用できませんでした。
一応わかった範囲の情報をここに書きます。

LCDは「LCD HD44780準拠LCD (QAPASS 1602A)」です。
このLCDに、I2C変換用のIC、PCF8574A が接続されています。
I2Cは、0x3Fで通信ができるようで、i2csetなどで、おそらく表示させることができます。
このLCDを動作させるためには、上記で記述したように5V通信を行うように、
間にI2Cバス用双方向電圧レベル変換モジュール(PCA9306)が必要です。
そして、Arduinoでは、LiquidCrystal_I2Cで通信できるのですが、これはラズパイでは使用できないので、他の方法でLCDと通信します。
結局、いろいろ調べて下のようなことをしたのですが、私はLCDに何も表示できませんでした・・・。
Python code for a 16×2 LCD via I2C gives alternate results
i2c display aansluiten aan de Raspberry Pi
最後に注意点として、このLCD、買った時からショートしている部分がありました。(5VとGNDがショートしてて、危険だった。)
一応、接続する前に確認した方がいいです。

そんなこんなで、「Arduinoをはじめよう 互換キット 20 in 1」買うよりは、
Raspberry Pi 用のを買ったほうがいいです!

あとは起動時の注意事項や、設定などのメモです。


ラズベリパイの設定を行う

sudo raspi-config

CUIからは、このコマンドで設定が行えます。
GUIの場合は、スタートメニューから設定が行えます。
ここで、日本語の入力設定が可能です。
ただし、日本語の設定は、後述のフォントの設定をする前にすると、
文字化けしてしまうので、行わないように注意しましょう。
SSHを実行できるようにしたい場合は、ここで設定が行えます。
※恐らくSSHのデフォルトはONになっているはず。


日本語フォントのインストール

sudo apt-get install ttf-kochi-gothic xfonts-intl-japanese xfonts-intl-japanese-big xfont-kaname

このコマンドで日本語フォントをインストールできます。
ただし、明朝体なので画面表示にはむいていません。

sudo apt-get install fonts-vlgothic

ネットにつながるようになったら、上のようにゴシック体のフォントをインストールしましょう。


日本語入力に対応

sudo apt-get install uim uim-anthy

または、

sudo apt-get install ibus-mozc

上記の2種類の方法があるようです。
恐らく両方ともネットにつながってないとダメです……。
下のibus-mozcの方が使いやすそうです。


無線LANをつなげる

無線LANのUSBを接続してください。

lsusb

これで、接続したデバイスが表示されます。

Bus 001 Device 005: ID 2019:ab2a PLANEX GW-USNano2 802.11n Wireless Adapter [Realtek RTL8188CUS]

そして、次に無線LANの設定をします。

wpa_passphrase SSID PASSWORD

これを入力すると、ずらーっと文字が表示されます。

network={
	ssid="***"
	#psk="***"
	psk=***
}

その文字をコピーして、「/etc/wpa_supplicant/wpa_supplicant.conf」のファイルの最終行に追加します。
下記のコマンドで、ファイルを開けますので、

sudo leafpad /etc/wpa_supplicant/wpa_supplicant.conf &

最後に貼り付けをします。

sudo /etc/init.d/networking restart

あとはこれで、設定を反映します。

ifconfig

ifconfigを実行して、wlan0 があり、いろいろ設定が値が表示されると成功です。

最後は、下記のコマンドを実行すれば、IPアドレスが割り当てられて使用できるようになります。

sudo dhclient wlan0

リモートデスクトップを行えるようにする

ネットワークが繋がった状態で、下記のコマンドを実行します。

sudo apt-get install tightvncserver

あとは、リモートデスクトップを実行します。
初回起動時のみ設定を入力する必要があります。

tightvncserver

Windows環境では、TightVNC を使用するとよいです。
ダウンロード\その他全ファイル\TightVNC-win32\1.3.10\tightvnc-1.3.10_x86_viewer.zip
をダウンロードして実行します。
中にある実行ファイルを起動して、「***.***.***.***:5901」(IPはifconfigで調べておく)
を実行するとリモートデスクトップが可能となります。


固定IPアドレスにする

デスクトップ環境で以下を入力します。

sudo leafpad /etc/network/interfaces &

下記の部分を見つけて、

allow-hotplug wlan0
iface wlan0 inet dhcp
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

下のような感じで値を変更して、上書きします。

allow-hotplug wlan0
iface wlan0 inet static
address 192.168.11.65
netmask 255.255.255.0
gateway 192.168.11.1
    wpa-conf /etc/wpa_supplicant/wpa_supplicant.conf

最後はいつものように設定を反映させて設定終わりです。

sudo /etc/init.d/networking restart

※2016年現在のOSでは、この方法は使用できません。詳細は「Raspberry Pi はじめました (第4回)」を参照。


自動起動させる方法

下記のファイルが、起動時に自動実行されるので、
この「/etc/rc.local」に実行権限をつけたうえで、中身を書き換えればいい。

/etc/rc.local

・・・という文章を、ネットでみかけたのですが、うまくいかず。

cron に追加する方法を今回書きます。
cronでvncserverを自動起動する を参考にしました)
cron というのは、スケジュールで様々なものを起動させたりするソフトで、
例えば、1時間に1回起動させる、起動時に1回起動させるなど、いろいろ設定できます。

では、まず・・・

nano

と実行して、エディタを開き

次のようにVNCサーバーが立ち上がるように書きます。

#!/bin/sh

#startup script

tightvncserver &

exit 0

そして、下記のディレクトリにファイルを保存します。

/home/pi/startup.sh

ファイルは、実行権限をつけておきます。
chmodは、権限を設定するコマンドです。

sudo chmod +x /home/pi/startup.sh

そして、いよいよ cron の設定です。
次のように実行してください。

sudo crontab -e

最初に、どのエディタで開くか聞いてくるので、好きなのを選びます。
あとは、下記を最後の行に追加して上書きします。

@reboot su -c "/home/pi/startup.sh" - pi

これで、Raspberry Pi が起動すると、
「/home/pi/startup.sh」が実行されて、VNCサーバーも起動します。


Windows上から直接ファイルを編集できるようにする

リモートデスクトップでもいいのですが、
やはり、ファイルは直接編集できたほうがとても楽です!
ここでは、sambaを使用してファイルサーバーを作ります。
Raspberry Piを共有ファイルサーバーにしてみた(Samba)を参考にしました!)

まず、sambaをインストールします。

sudo apt-get install samba

次の設定ファイルを開いて……

sudo nano /etc/samba/smb.conf

最終行に次を追加します。
browseable は、Windowsのネットワーク一覧に表示されるようになります。

[pi]
path = /home/pi
read only = No
guest ok = No
force user = pi
browseable = Yes

そして、ユーザーアカウントpi のパスワードを設定!

sudo pdbedit -a pi

最後に、設定を更新して終了です。

sudo service samba-ad-dc restart

インストーラー形式じゃないものを管理する

通常、installコマンドでインストールできますが、
中には、makeしてインストールするものとかもあります。
このようなソフトを、通常のパッケージのように管理するソフトがpacoです。

sudo apt-get install paco

paco については、「pacoでソースビルドをパッケージっぽく管理する」を参考に。


喋らせるようにする

下記のファイルが必要です。
・hts_engine
・Open JTalk
・辞書ファイル open_jtalk_dic
・MMDAgent音声ファイル

Raspberry Piにしゃべらせてみた(OpenJTalk 1.08、.htsvoiceファイル対応)」がおすすめです。

Written by なたで

2015年12月24日 at 00:26

カテゴリー: memo, program

Tagged with