ロボットプログラミングで遊んだ

Qumcumという学習用のロボットがあると知り合いに教えてもらったため、買ってみて遊んでみた。Qumcumはその知り合いが学生時代の時の教員だったらしい。Qumcumは自分で組み立てを行い、プログラミングして動かせるようなロボットである。組み立てはドライバーがあれば可能で、プログラミングはScratchかArduinoを用いて行う。

パーツ

パーツは以下のような感じで結構種類がある。小学生でも出来るという触れ込みだが、パーツ組み立てには大人がいないと難しいかもしれない。

Qumcumのパーツ
Qumcumのパーツ

組み立て

組み立ての工程は以下のような感じになる。組み立てる最中はドライバーでネジを締める必要があるのだが、結構な力が必要なので、やはり大人の力も欲しいところである。さらに、雑に組み立てると壊してしまいそうな箇所もあるため気をつけたい。

Qumcum組み立て1Qumcum組み立て2Qumcum組み立て3
Qumcum組み立て

完成

完成は以下のようになる。大人が組み立て終わるのに2時間ぐらいかかったので、結構な作業な気もする。組み立て方法はQumcumの公式サイト (ロボットの組み立て方1-まずはじめに – Qumcum)にあるため、特に迷う事は無かった。

Qumcum完成
Qumcum完成

プログラミング

Qumcumのプログラミングは基本的にScratchで行うらしいが、Windows環境が無いためArduinoを使って実装してみた。Arduinoでのプログラミング方法も、公式サイト(Tutorial - Arduino de クムクム)に載っているため非常に簡単に動かすことが出来た。BLEでも接続できるっぽいが、BLEでのプログラミング方法の詳細は載っていないため自分で調べる必要がありそうだ。

動かしてみた結果は以下の通り。基本的に上記のチュートリアルそのままで以下を実行可能で非常に簡単である。というかArduinoの隠蔽が凄くて、電源やI2Cなどの複雑なコードについてはほとんど考える必要なくプログラミングが出来る。サーボモーターを動かしたり、音声読み上げを動かしたり出来るので、なかなか面白い。

最近の小学生は、こういう教材を用いてプログラミング学習をするらしい(Qumcumロボットのそごう体験会を開催 – 株式会社CRETARIA)。自由研究とかにも良いのでは無いだろうか。小学校の自由研究に割り箸で五重塔を作っていた自分からすると、文字通り隔世の感である。

自作言語BLispがHackers Newsで話題になっていた

現在、BLispというプログラミング言語を設計・実装中で、基本機能は出来たので、とりあえずのドキュメントを作成して公開した。

https://ytakano.github.io/blisp/index.ja.html
https://github.com/ytakano/blisp

これを公開したのが2021年2月21日頃だが、6月末頃に急にGitHubリポジトリにスターがつき始めたため、何事かと思っていたら、どうやらHackers Newsで話題になっていたようだ。

https://news.ycombinator.com/item?id=27640984&noRedirect=true

Hackers Newsとは、日本で言うところのはてなブックマークみたいなもので、気に入ったサイトをみんなでブックマークしあうものである。自分も昔はHackers NewsやRedditを読んではいたが、ここ最近は見なくなって久しい(はてなブックマークは見ている)。

BLispはRust用のインタプリタ言語、シェルとして開発しており、エフェクトシステムという機能を持っているのが特徴である。Rustはとても良い言語なのは言うまでも無いが、それを操作するためにはインタプリタ言語的な機能はどうしても欲しくなる。BLispはそれを型安全に行うために設計・実装している。自動化スクリプトの記述にYAMLなどを使うのは地獄じゃ無いですか?

そんなこんなで現在ちまちまと実装中だが、まさかHackers Newsで取り上げられるとは思わなかった。Hackers Newsに投稿されたコメントを見ると、エフェクトがあるのが素晴らしいなどと言った、不失正鵠なコメントもあり、さすが世界だなと感じた。

その一方、静的型付けにするとLispのようなマクロは使えないというコメントが一番盛り上がっていた。Lispのマクロというと、構文木(というかS式)の操作が可能なのが特徴である。しかし、これは別にLispや、動的型付けと関係なく実現できる。実際、RustやNimと言ったプログラミングではマクロで構文木を操作することが可能である。

パーキンソンの凡俗法則と呼ばれる経験即が知られている。これは、誰もが参入しやすい話題であるほど議論が白熱するという経験即である。マクロというのは一般的なプログラマーなら誰もが知っている内容であるため議論しやすかったのだろうと、興味深くスレッドを見ていた。このあたりは世界も日本も同じである。

ともあれ、Hackers Newsで指摘があったようにマクロは必要に思うので、近いうちに実装したいと思う。それでは皆さん、良いハッキングライフを。

【読書メモ】廃園の天使IとIIを読んだ

早川書房のセールがKidleストアでやっていたため、Amazonの欲しいものリストに入れたままずっと買っていなかった、『グラン・ヴァカンス 廃園の天使 Ⅰ』と『ラギッド・ガール 廃園の天使 Ⅱ』を買って読んでみた。ずっと欲しいものリストに入っていたため、何故入れたのかは覚えていない。何故だろうか。初めに感想だけ言うと、グラン・ヴァカンスはSFと言うよりも文学作品っぽくてあまり面白さは分からなかったが、ラギッド・ガールはこれでもかと言うほどにSFをしていて非常に楽しめた。グラン・ヴァカンスは読むのに1ヶ月かかったが、ラギッド・ガールは2日で読み終えてしまった。しかし、グラン・ヴァカンスの内容があるからこそ、ラギッド・ガールの面白さがあると思うので、読む場合は両方読んで欲しい。

良質なSF作品は科学の皮を被った哲学作品である事が多く、ラギッド・ガールは意識と生命に関する哲学を主題としている。最近はAIの流行から、人工生命の人権なども語られるようになってきており、人工知能がシンギュラリティを超えるとの言説も多くなっている。ラギッド・ガールもそれらの例に漏れずに人工知能や人工生命の意識、人権を主題としてはいるのだけれど、それらとひと味違うのは、シンギュラリティをどうやって超えたかの説明を科学的な理由づけで説明しているからである。多くのSF作品では、人工知能や人工生命はどうやって生み出されたかという説明は無しに、とりあえず可能になったという前提で話が進む。しかし、それらはAI全盛の昨今ではどうしても似たり寄ったりの説明になってしまうが、本作では技術的な壁とその解決策が空想ではあるが科学的に解説されていて大変面白かった。

人間のシミュレーション

人間の意識を生み出す最も自明な方法は、人間の細胞の一つ一つの動きをすべてシミュレーションすることである。しかし、これには以下のURLにあるように、計算量の問題が出てくる。

Teleportation: will it ever be a possibility? | Technology | The Guardian

この記事によると、人間は約32兆個の原子から成り立っており、それを表すためには2.6 \times 10^{42}ビット=\frac{2.6 \times 10^{42}}{8}バイトの情報量となるらしい。2^{10} = 1024バイトが1KiB、2^{20} = 1024KiBが1MiB、2^{30} = 1024MiBが1GiB、2^{40} = 1024GiBが1TiBである。ということは、人間の原子を丸々シミュレーションするためには、272848410531878471374511718750TiBもの情報量を扱わなければならない。

スパーコンピュータ富嶽の性能は公称415.53PFLOPSなので、秒間415.53 \times 10^{15}回の浮動小数点演算を行える。1回の計算で8バイトのデータに対しての計算を行えると仮定すると、\frac{2.6 \times 10^{42}}{8 \times 8 \times 415.53 \times 10^{15}} \approx 90246191610714027868024\approx 2859729244641988年あれば、人間シミュレーションの1ステップ分を行える計算になる。

意識や人間のシミュレーションを行うには、この計算量の壁をどう乗り越えるかが重要になる。ちなみに、漫画GANTZでは人体の転送を行っているが、あのレーザーの転送速度は異次元の速度であり、エネルギー消費量も異次元である。肉体転送レーザーの技術に比べると、GANTZから与えられる武器はおもちゃ以下の性能しか無いと言って良いだろう。転送レーザーに使っているエネルギーを転用すれば、すべての問題が解決すると思われる。

話がそれたが、意識のシミュレーションは現状では本当に難しく、おそらく量子コンピュータで作られたコンピュータが一般的になるレベルにまで科学技術が進展してようやく先が見えるかどうかぐらいだと思う。そのような状況になるのがいつかは分からないが、その時にどうやって解決するかは、ラギッド・ガールを読むことで妄想することができ、大変面白かった。続編も執筆中らしいので期待したい。

【読書メモ】ビット・プレイヤーを読んだ感想

グレッグ・イーガン「ビット・プレイヤー」を読んだ。グレッグ・イーガンはSFの巨匠らしく、いろいろなジャンルのSFを書いているらしい。最近、ちまちまと短編SFを読んでいるが、本作はシンギュラリティを超えたストーリーの作品が多かった。シンギュラリティを超えるというのはつまり、ソフトウェアに意識が芽生えたり、人類の精神をデータに変換して物質に復元したり、恒星間航行が可能になるということである。本書の感想は、全体ではイマイチに感じたが、最後の「孤児惑星」は面白かったというの正直なところである。

有人での恒星間航行を行う際にはいくつかの方法がある。

ワープはスターウォーズシリーズなどで用いられる方法であるが、やや安直すぎる。ワープ(超高速航行)を実現する方法として、アルクビエレ・ドライブという方法が知られている。アルクビエレ・ドライブを簡単に説明すると、宇宙船の後方にビッグバンを発生させ、前方にビッグクランチを発生させ時空をゆがませて進む方法である。ビッグバンやビッグクランチを継続的に発生させるって何回宇宙創造するつもりだよとは思う。しかし、よく考えてみると、実は、我々の居る宇宙というのは、高次の存在者がアルクビエレ・ドライブで発生させた宇宙、つまりワープ中の燃えかすという可能性も出てくる。

精神のデータ化は本作で頻繁に出てくる。しかし、精神がデータ化できてしまうと、死やら個人のアイデンティティーやらそういうものが崩壊しているのではという気になる。死んだとしてもバックアップはあるし無茶も出来る。精神のデータ化やバックアップが出来る作品はままあるが、比較的多くの作品で、1人格は同時刻に唯一の物理的存在しか登場しないことがままある。本作品でも比較的容易にバックアップが稼働できるという描写があるが、バックアップ出来るならクローンを作れば良いのにと思いながら読んでいた。空の境界蒼崎橙子も同じく同時に稼働は出来ないが、こちらは魂は1つとかいう理屈づけがされていたように思う。しかし、精神のデータ化はまだまだ出来そうに無いなとは思う。精神をデータにするには、個人的には脳だけではなく、数億か数兆かわからないが、いわゆる5感と言われるセンサ類もデータ化する必要があるのでは無いかと思っている。脳が精神なのでは無くて、精神はペリフェラルも含めた分散アーキテクチャになっているのではないだろうか。

箱船はいわゆるシドニアの騎士方式で、なかなか現実的だと思う。箱庭を実現するためにはいくつか超えなければならない課題がある。1つめは生物の循環系をクローズドな環境で再現できるかという課題である。実は、これについては過去にアメリカで、バイオスフィアと呼ばれる研究施設が設立されて研究されいたが、この研究は見事に失敗している。最近ではイーロン・マスクが火星移民をうたっているが、少なくとも、まずは地球上で人工閉鎖生態系を完成させなければならないだろう。2つめは宇宙空間における巨大建造物である。箱船に、はじめに最低1000人規模の人間が乗り込むとしても、数百年の航行(もっとか?)と人口増加を見据えて、1万人は収容可能な規模がほしい。ガンダムのコロニーは数億から数十億人規模を収容可能だそうだが、あれだけの巨大建造物を作る技術は我々人類にはまだ無い。しかも、これだけの巨大建造物を作成しても、たかだか数十億人しか収容できないため、増えすぎた人類が宇宙に移民したところで、すぐに人口問題が噴出するのは火を見るより明らかである。ただ、箱船は超科学的な発展が無くとも、エンジニアリング的な試行錯誤を重ねていけば到達可能には思える。

コールドスリープは亀や金魚とかなら可能だろうが、人類で行うのは現状では厳しいそうだ。コールドスリープはあまり詳しくないので、詳細は適当なサイトを見てほしい。

ビット・プレイヤーはカジュアルに超技術が出てくるため、色々と思いを巡らせて読んでいた。しかし、恒星間航行や精神のデータ化はさすがにしばらくは実現しないだろうと思う。個人的な予測では、まず宇宙か月あたりに金持ち向けのホテルが出来るのでは無いかと思っている。と思ったら、構想中であった。

www.cnn.co.jp

短期滞在なら可能な事は既に実証済みだし、これぐらいは出来るだろうが、凄いなあ。

RustでHello, World!

環境構築

実験用のOSはUbuntu 20.10、x86_64を想定します。

まず、Rustの環境を整えます。Rustの環境はrustupで構築できるので簡単です。Rustには大きく分けてstableとnightlyがあるのですが、今回はnightlyを利用します。具体的には以下のようにコマンドを入力するとインストールできます。

$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | \
  sh -s -- --default-toolchain nightly-2021-03-06 \
  --component clippy rust-src llvm-tools-preview rustfmt rls rust-analysis rustdoc -y

インストール後はenvファイルを読み込んで環境変数を設定します。

$ source $HOME/.cargo/env

次に、必要なソフトウェアをaptからインストールします。

$ sudo apt update
$ sudo apt upgrade
$ sudo apt install build-essential zsh git curl libncurses5-dev libtinfo5 clang lld fakeroot xz-utils libssl-dev bc flex libelf-dev bison llvm cpio qemu-system

Linuxカーネルコンパイル

次に、Linuxカーネルソースコードを取得します。今回は、linux-nextという次世代Linux向けの実験的なソースコードを使います。

$ git clone --depth 1 git://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git

続いて、Linuxカーネルコンフィグを設定します。

$ cd linux-next
$ make menuconfig

設定項目は、以下の通りです。General setup ---> Rust support ---> yesと、Device Drivers ---> Character devices ---> Rust Example ---> yesは必ずオンにしておきましょう。他の項目は、以下にチェックがあれば問題ないと思います。様々なオプションをオンにしたままだと、コンパイルに時間がかかるので最小オプションにしておきましょう。

64-bit kernel ---> yes
General setup ---> Rust support ---> yes
General setup ---> Initial RAM filesystem and RAM disk (initramfs/initrd) support ---> yes
General setup ---> Configure standard kernel features ---> Enable support for printk ---> yes
Executable file formats / Emulations ---> Kernel support for ELF binaries ---> yes
Executable file formats / Emulations ---> Kernel support for scripts starting with #! ---> yes
Device Drivers ---> Generic Driver Options ---> Maintain a devtmpfs filesystem to mount at /dev ---> yes
Device Drivers ---> Generic Driver Options ---> Automount devtmpfs at /dev, after the kernel mounted the rootfs ---> yes
Device Drivers ---> Character devices ---> Rust Example ---> yes
Device Drivers ---> Character devices ---> Enable TTY ---> yes
Device Drivers ---> Character devices ---> Serial drivers ---> 8250/16550 and compatible serial support ---> yes
Device Drivers ---> Character devices ---> Serial drivers ---> Console on 8250/16550 and compatible serial port ---> yes
File systems ---> Pseudo filesystems ---> /proc file system support ---> yes
File systems ---> Pseudo filesystems ---> sysfs file system support ---> yes

つづいて、Hello Worldを出力するようにします。

./drivers/char/rust_example.rsを修正して、Hello Worldを出力するように修正します。

$ cat ./drivers/char/rust_example.rs

修正箇所は、FileOperationsの実装にTO_USEを設定し、read関数を追加します。read関数内でHello, World!を出力するようにします。具体的な修正箇所は以下の通りです。そのほかの部分は修正しなくても大丈夫です。

use kernel::{
    chrdev, condvar_init, cstr,
    file_operations::{FileOperations, File, ToUse},
    user_ptr::UserSlicePtrWriter,
    miscdev, mutex_init, spinlock_init,
    sync::{CondVar, Mutex, SpinLock},
};


impl FileOperations for RustFile {
    type Wrapper = Box<Self>;

    const TO_USE: ToUse = ToUse {
        read: true, // read関数を有効化
        write: false,
        seek: false,
        ioctl: false,
        compat_ioctl: false,
        fsync: false,
    };

    fn read(&self, file: &File, data: &mut UserSlicePtrWriter, _offset: u64) -> KernelResult { // read関数を定義
        println!("rust file: read, pos = {}", file.pos());
        if file.pos() == 0 {
            let hello = b"Hello, World!\n";
            data.write_slice(hello)?;
            Ok(())
        } else {
            Ok(())
        }
    }

    fn open() -> KernelResult<Self::Wrapper> {
        println!("rust file was opened!");
        Ok(Box::try_new(Self)?)
    }
}

コンパイルします。

$ make -j 8

busyboxコンパイル

次にbusyboxソースコードを取得します。

$ git clone git://busybox.net/busybox.git

設定します。

$ cd busybox
$ make defconfig
$ make menuconfig

設定では以下のように静的リンクのオプションをチェックします。他の設定は触らなくて大丈夫です。

Settings ---> Build Options ---> Build static binary (no shared libs) ---> yes

コンパイルしinitial RAMディスクを作成します。initial RAMディスクはlinux-nextにおいておきましょう。

$ make -j 8
$ make install
$ cd _install
$ mkdir dev proc sys
$ find . | cpio --quiet -H newc -o | gzip > ../../linux-next/initrd.img

Qemuで実行

最後に仕上げとして、Qemuで実行します。

$ cd linux-next
$ qemu-system-x86_64 -m 128M -kernel arch/x86_64/boot/bzImage -append "console=ttyS0 rdinit=/bin/sh root=/dev/ram0" -initrd initrd.img -nographic

QemuLinux起動後は、devtmpfsをマウントします。

# mount -t devtmpfs devtmpfs /dev

最後に、/dev/rust_miscdevファイルをcatして、Hello, World!を出力します。

# cat /dev/rust_miscdev
[ 4362.809581] rust file was opened!
[ 4362.809787] rust file: read, pos = 0
Hello, World!
[ 4362.810056] rust file: read, pos = 14

素晴らしい!Rustで無事にHello, World!を出力することが出来ました。

シン・エヴァンゲリオン劇場版を視聴した(ネタバレあり感想)

最近、眉をしかめることがあった。研究室には事務作業をしてくれる事務の方が居るが、自分で取ってきた研究費を用いた物品調達は研究室事務に依頼するのを禁止された。ボスの研究費のみ依頼可能らしい。なるほど。まあいいだろう。これぐらいのハラスメントは日常茶飯事だ。見るがいい、これがアカデミアだ。

そんなもやもやを抱えながら、シン・エヴァンゲリオン劇場版を観に行った。エヴァとは付き合いが長い。もうかれこれ25年ぐらいだ。当時の友人が筋金入りのオタクで、その友人宅でエヴァを見た。すぐにはまった。旧劇を見るために、午前4時から映画館に並んだ。当時はインターネット予約といった先進的なシステムは無く、並んでチケットを買ったものだ。映画のチケットを買うとレイかアスカのテレフォンカードを購入できるのだが、迷わずレイを選んだ。友人は当然のごとくチケットを2毎購入し、レイとアスカの両方を手に入れていた。どっちつかずの八方美人はいけない。本命に絞って購入するのが男だ。Airは良い。アスカの覚醒シーンは最高の一言だ。まごころを、君には良くわからなかった。しかし、納得できないという気持ちの一方、やっぱりエヴァだったなという安心感もあった。エヴァはこうでなくては。

序、破も最高に面白い。これがエンターテインメントだ。シン・ゴジラも良かった。アニメの監督がここまで面白い実写映画をつくれるとは思ってもみなかった。しかしQは何だ。意味不明だ。ヴンダーとは?いきなりの艦隊戦はエヴァとは違うのではいか?そんな思いが巡ったが、その一方で、やはりエヴァだなと妙に納得している自分もいた。エヴァはやはりこうで無いといけない。普通の終わり方などあり得ない。これこそがエヴァお家芸で、これだからこそこれだけ長く愛されているのだ。完全に調教済みである。

シン・エヴァンゲリオン劇場版を観に行った。エヴァが終わると聞いていたが、にわかには信じられなかった。エヴァが終わる?本当に?あのエヴァだぞ。そう思いながらIMAXシアターの席に座っていた。映画が始まる。冒頭のシーンはAmazon Prime Videoで視聴済みだ。前日、前々日に序・破・Qも再履修した。

シーンが移り変わり、綾波が農作業していた。あの綾波が。私は人形じゃ無いと言っていた、どう見ても人形の綾波が、おはよう、おやすみ、こんにちは、さようならとあいさつをしている。綾波は魔法の言葉を覚えていた。あいさつするたび、ともだちが増えていっていた。なんと言うことだ、あの綾波がここまでの成長をみせている。もうこの時点で涙腺は駄目になっていた。これが尊い?信仰に近い感動を表す言葉。初めての気持ち。綾波は様々な感情を学び、自分は尊いを学んだ。色々あった現実世界のもやもやなど既に忘れていた。しかし、まだ映画の前半だ。エヴァがこのまま平和に終わるわけが無い。先のことを考えると暗澹たる気分になった。

映画は続き、いよいよ終盤にさしかかる。もしかして、本当に、本当の本当におわるのか?そんな考えが頭によぎった。エヴァが終わる。それが確信に変わったとき、奇妙な感動が押し寄せる。庵野秀明監督、お疲れ様でした。そういう思いやら何やらが色々まざりあい、変な感動が押し寄せる。作品自体の面白さとか、そういう客観的な判断を下すのは既に不可能となっていた。実際、序・破・Qから見た新規の客に受ける内容かはわからない。アスカ、ゲンドウ、それぞれのキャラクターが救済されていく。輪廻転生の輪から解脱していく。ああ終わるんだな、そう思わせてからの、渚指令。さすがエヴァだ。これだよ。エヴァはこうでなくっちゃ。納得のいかない終盤シーンに、妙に納得していた。

帰り際、近くの本屋に寄った。その本屋の科学雑誌コーナーには、日経サイエンスニュートンが売られており、その間にムーが鎮座していた。綾波も成長するんだ、ムーだって成長する。そう感じた。

BLisp言語のドキュメントを作成しcrates.ioに登録してみた

BLispはRust言語で実装されたベアメタル環境で動作するシェル、API定義言語として現在研究・開発をすすめています。動機は2つあります。1つが、せっかく静的型付けで型安全なRust言語を使っているのだから、Rustと協調動作するスクリプト言語でも静的型付けで型安全になってほしいというもの。もう1つは、副作用をエフェクトシステムで分離したいというものです。後者については過去に記事を書いていますので、そちらをご覧ください。

ytakano.hatenablog.com

せっかく作ったのだから、そのドキュメントを作成しておこうと思い、簡単なものを作成しました。ドキュメントはまず英語で書いて、それをDeepLで日本語で翻訳して多少手直ししています。DeepLすごいですね。

BLisp: Lispっぽい静的型付け言語

BLisp: A Statically Typed Lisp Like Language

crates.ioへの登録

せっかくなのでcrates.ioへも登録してみようと思い、こちらにも登録してみました。

https://crates.io/crates/blisp

Cargoでは、Cargo.tomlに依存ライブラリを記述すると、crates.ioからダウンロードするのですが、このcrates.ioへの登録も非常に簡単にできることがわかりました。実は、crates.ioとgithubは連携しているのかなと勝手に想像していたのですが、全くそういうことは無く、crates.ioへパッケージを登録するのだという気づきがありました。何事もやってみるものですね。

機能アップデート

機能アップデートとしては、map、foldの基本的な関数と、OptionとResult型を内部的な関数・型として追加しています。また、多倍長整数をサポートしましたので、ベアメタルで巨大な数も扱えるようになります。

ところで、実装には、Rustのbig-integerを使ってみたのですが、ベアメタル環境にもかかわらず、Display部分でfmod関数を呼び出しているようなので、そこを回避する必要がありました。llvmのコード生成時にfmodを呼び出していそうなのですが、定かではありません。

動作としては以下のような感じとなります。no_stdで動くので、WASMでも動くのではと思っており、いずれチャレンジしてみたいところです。それでは皆さん、良いRust生活を。

f:id:ytakano:20210221155657g:plain

ベアメタルで動くBLisp