memo

セカンドライフのテクスチャの秘密1

投稿日: 更新日:


はじめに

こんにちは!

久しぶりのブログです。

今日は、セカンドライフのテクスチャ、ノーマルマップ  の秘密について話します。
続かないかもしれませんが、とりあえず第1弾です。


ノーマルマップの色成分の基礎

ノーマルマップといえば、平面の凹凸を現した画像です。
通常グレースケールで高さを表した画像から、このノーマルマップを作成します。
おそらく、少し詳しzい方はこの辺までは、ご存知かと思います。

しかし、具体的に
赤色成分は、何をセカンドライフ上の何を示すのか、
青色成分は……?
といったことまで知っている方はそんなにいないのでは?

ということで、この色成分が何を表しているかの解説となります。

ノーマルマップの英語の解説を確認してみましょう。
これを見ると、次のような情報が分かります。
赤成分R = 方向成分X
緑成分G = 方向成分Y
青成分B = 方向成分Z

ただし、方向とは言ってもX+がR+に
対応しているのかといったことはテキストには書いてありません。
なぜ、それが重要かといいますと、ソフトによって色成分との対応が異なるためです。

>・ZBrush:(-X,+Y,+Z)
>・CrazyBump:(+X,+Y,+Z)
>・Blender 2.4x:(-X,-Y,+Z)
>・Blender 2.57以降:(+X,+Y,+Z)
Sandy Virtual City様のブログから引用
※XYZ軸がどちらに対応しているかも重要となるため、ブログ内の軸の解説も参照しましょう。
ブログでは、X軸のプラスをUV座標系のU方向、Y軸のプラスをUV座標系のV方向、Z軸のプラスを凸方向としています。

では、セカンドライフを調べてみましょう。
公式ページにあるノーマルマップの画像から、
凸に対して、画素の色が次のようになっています。
上が RGB(126,178,212)
右が RGB(169,124,210)
下が RGB(109, 75,206)
左が RGB( 69,124,212)

つまり、セカンドライフ(+X, -Y, +Z)
となることが分かります。

これは、NormalMap-Onlineでは、
Invert の R にチェックが入った場合と同様になります。

これらをおさらないすると、たとえば下記のようなバンプマップ/ハイトマップを用意したとすると、

次のような画像がセカンドライフ上でのノーマルマップとなります。

本日は、ここまで!

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

投稿日: 更新日:


次のような自分の行動の情報を取得してみます。
・自分が喋った回数
・人から聞いた回数(アバターが話したものに限定)
・空を飛んでいる時間(ホバーは含めない)
・海の中を泳いでいる時間(ホバーは含めない)
・歩いている時間
・走った時間
・ジャンプ中の時間
・テレポートした回数
・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 ログイン、装備
		}
	}
}

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

投稿日: 更新日:


こんにちは!

昨日から引き続き、「セカンドライフ技術系 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日 セカンドライフでアニメーション
セカンドライフでアニメーションを作る方法!

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

投稿日: 更新日:


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

ついに今年も「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);}}

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

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

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

GeForce GTX の発色を鮮やかにする方法

投稿日: 更新日:


えNVIDEA GeForce GTX のディスプレイ設定をいじって、鮮やかな画面にする方法を紹介します。

NVIDEA コントロールパネルを開いて、ディスプレイのデスクトップカラー設定の調整を開きます。
nvidea_control_panel_1

ここで、コントラストと、デジタルバイブランスという設定をいじります。

コントラストは明暗の差。デジタルバイブランスは彩度の設定です。

nvidea_control_panel_2
nvidea_control_panel_3

コントラストとデジタルバイブランスを両方とも+50%→+55%にするだけで、かなり鮮やかな画面になります。

ゲームするときは、あえてすこしいじって遊ぶと、より世界が鮮明になり
また違った楽しみ方ができるとおもいます!

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

投稿日: 更新日:


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"

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

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

投稿日:


今まで
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

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