秋葉原の“昔ながらの”部品屋さんが集まる「秋葉原ラジオストアー」が64年の歴史に幕を閉じ、2013年11月30日で閉館すると発表されました。「秋葉原ラジオストアー」は、その名前までは認識していなくとも「JR秋葉原駅から中央通りに出ようとすると見かける、ガード下のごちゃっとした素人お断り風の路地」といえばわかりますでしょうか。あの一角はいくつかの建物?の集合体なのですが、そのうちのひとつが「秋葉原ラジオストアー」です。秋葉原はラジオ(電子部品)の街→電気製品の街→PCの街→萌えの街、というような変遷を経ていますが、この「電子部品の街」の頃から全くその景色が変わっていない、ザ・秋葉原という雰囲気を残す一角といえるでしょう。
その「秋葉原ラジオストアー」が閉館する!?と聞き、昔からの秋葉原ユーザとしてはいてもたってもいられずRICOH THETAを持って、あの雰囲気を記録するために「勝手ストリートビュー」を撮影してまいりました。衝動的に、勝手に撮ってしまいましたごめんなさい!
上記地図の青丸が撮影地点です。順に地図右側から、画像をクリックするとパノラマに飛びます
地図上のお店が赤く示されているところが「秋葉原ラジオストアー」です。通路をはさんで反対側は「ラジオセンター」という別の建物で、こちらは今回閉館のアナウンスはありません。このあたり、ラジオストアーが閉館したらどういう景色になるんでしょうか…。
今回の撮影はRICOH THETAを頭上にかかげ、自作スクリプトで5秒に一回リモートシャッターで自動的にシャッターを切り続けるようにセットしそのまま通路を歩いて撮影しました。通路の端から端まで1分くらいでしょうか。THETAの機動力の高さが活かせたかなと思います。
参考までに、THETAでリモートシャッターを切るスクリプト(Perl)を以下に示します。AndroidではSL4A+Perl for Androidの組み合わせで端末上で実行可能です。本スクリプトはシャッターを1回切るだけですが、PTP_OC_InitiateCaptureの部分を繰り返すことで複数回シャッターを繰り返させることが可能です。
THETAはWiFi経由ではPTP-IPで通信しているようで、制御はこちらのドキュメントなどを参考にしました。
※このスクリプトはその後バージョンアップしています。詳細はこちらのページをごらんください
#!/usr/bin/perl
# -------------------------------------------------------
# RICOH THETA Remote shutter
# -------------------------------------------------------
use IO::Socket;
#use Encode;
# ----- TARGET THETA
my $Addr = "192.168.1.1";
my $Port = 15740;
# ----- My profile
my $Name = "THETA_Shutter";
my $GUID = "8a7ab04f-ebda-4f33-8649-8bf8c1cdc838";
my ($command_sock, $event_sock, $result, $session_id, $transaction_id);
# Init_Command
$command_sock = &PTPIP_Open_Connection;
&PTPIP_Init_Command_Request($command_sock);
($result, $session_id) = &PTPIP_Wait_Init_Command_Ack($command_sock);
if ($result == 0) { die "No Init_Command_Ack"; }
# Init_Event
$event_sock = &PTPIP_Open_Connection;
&PTPIP_Init_Event_Request($event_sock,$session_id);
($result) = &PTPIP_Wait_Event_Request_Ack($event_sock);
if ($result == 0) { die "No Init_Event_Ack"; }
$transaction_id = 0;
# PTP_OC_OpenSession
&PTPIP_Cmd_Request($command_sock, $transaction_id++, 0x1002, $session_id );
($result) = &PTPIP_Wait_Cmd_Response($command_sock);
if ($result == 0) { die "No Cmd_Response"; }
# PTP_OC_InitiateCapture
&PTPIP_Cmd_Request($command_sock, $transaction_id++, 0x100E, 0, 0 );
($result) = &PTPIP_Wait_Cmd_Response($command_sock);
if ($result == 0) { die "No Cmd_Response"; }
&PTPIP_Close_Connection($event_sock);
&PTPIP_Close_Connection($command_sock);
exit;
# -------------------------------------------------------
# Init_Command
# -------------------------------------------------------
sub PTPIP_Init_Command_Request {
my $sock = shift;
my $payload = "";
$payload .= pack("H8H4H4H4H12",split('-',$GUID)); # GUID
$payload .= Encode_UTF16LE($Name."\x00");
$payload .= pack("V",1);
print $sock &PTPIP_pack_command( 1, $payload);
}
sub PTPIP_Wait_Init_Command_Ack {
my $sock = shift;
my ($result,$session_id,$target_guid,$target_name,$unknown1);
my @error_response = (0,0);
my ($cmd,$payload) = &PTPIP_Recv_Response($sock);
if ($cmd != 2) { @error_response; exit; }
$session_id = unpack("V",$payload);
$payload = substr($payload,4);
my (@guid) = unpack("H8H4H4H4H12",$payload);
$target_guid = join('-',@guid);
$payload = substr($payload,16);
$target_name = Decode_UTF16LE(substr($payload,0,-4));
$payload = substr($payload,-4);
$unknown1 = unpack("V",$payload);
print "Target GUID :".$target_guid."\n";
print "Target Name :".$target_name."\n";
(1, $session_id);
}
# -------------------------------------------------------
# Init_Event
# -------------------------------------------------------
sub PTPIP_Init_Event_Request {
my $sock = shift;
my $session_id = shift;
my $payload = "";
$payload .= pack("V",$session_id);
print $sock &PTPIP_pack_command( 3, $payload);
}
sub PTPIP_Wait_Event_Request_Ack {
my $sock = shift;
my @error_response = (0);
my ($cmd,$payload) = &PTPIP_Recv_Response($sock);
if ($cmd != 4) { @error_response; exit; }
1;
}
# -------------------------------------------------------
# Cmd_Request
# -------------------------------------------------------
sub PTPIP_Cmd_Request {
my $sock = shift;
my $transaction_id = shift;
my $cmd = shift;
my @args = @_;
my $payload = "";
$payload .= pack("V",1);
$payload .= pack("v",$cmd);
$payload .= pack("V",$transaction_id);
$payload .= pack("V*",@args);
print $sock &PTPIP_pack_command( 6, $payload);
}
sub PTPIP_Wait_Cmd_Response {
my $sock = shift;
my @error_response = (0);
my ($cmd,$payload) = &PTPIP_Recv_Response($sock);
# if ($cmd != 4) { @error_response; exit; }
1;
}
# -------------------------------------------------------
# PTPIP utils
# -------------------------------------------------------
sub PTPIP_Open_Connection {
my $sock = new IO::Socket::INET(PeerAddr=>$Addr,PeerPort=>$Port,Proto=>'tcp',TimeOut=>2);
die "IO::Socket : $!" unless $sock;
$sock;
}
sub PTPIP_Close_Connection {
my $sock = shift;
close($sock);
}
sub PTPIP_pack_command {
my $cmd = shift;
my $payload = shift;
pack("VV",(length($payload)+8),$cmd).$payload;
}
sub PTPIP_Recv_Response {
my $sock = shift;
my ($buf,$len,$command_type,$packet_len);
my @error_response = (0,'');
# packet length
$len = read($sock,$buf,4);
if ($len != 4) { @error_response; exit; }
$packet_len = unpack("V",$buf);
if ($packet_len > 1024) { @error_response; exit; }
if ($packet_len < 8 ) { @error_response; exit; }
# command
$len = read($sock,$buf,4);
if ($len != 4) { @error_response; exit; }
$command_type = unpack("V",$buf);
# payload
$len = read($sock,$buf,$packet_len-8);
if ($len != ($packet_len-8)) { @error_response; exit; }
($command_type,$buf);
}
sub Encode_UTF16LE {
my $str = shift;
# encode('UTF16LE', $str);
pack("v*",unpack("c*",$str));
}
sub Decode_UTF16LE {
my $str = shift;
# decode('UTF16LE', $str)
pack("c*",unpack("v*",$str));
}
当初の目的だった「リモートシャッター」が動いたからもういいやー、とコマンドのレスポンスパース部を途中でほったらかしてありますがw、PTPIP_Wait_Cmd_Response の部分をもうちょっとちゃんと作って長いペイロードも受け取れるようになるといろいろとできる制御が広がるはず。そのあたりはまた後日、ということで。
この「勝手ストリートビュー」を作れる360度パノラマカメラ、RICOH THETAについては
に詳しくレビューしてありますので、よろしければこちらもどうぞ。






