感染症数理モデルでシミュレーションする(その1)

板橋区は来週の火曜日から休校になります。各自いろいろな意見があるわけですが、そのあたり代理戦争はせず、「自衛」という一点でこれを書き留めておきます。
というかですね、「クラスター対策」の説明がされていないような気がするし、検査がなぜ行われないか(あるいは行うのか)、どういう形で決定したのかわからないのが問題だと思うんですよ。個人的に。なので、個人的に調べて、個人的にブログに書き残すという方針なので、そのあたりはご容赦ください。

詳しい情報をたどる

から

2019-nCoVについてのメモとリンク

にたどり着いたあとに「なぜクラスター対策が重要か」

のところまで来て、

Dispersion vs. Control

ここにたどり着きました。

中澤さんのページのリンクがある

①(02251430大臣レク用)クラスター班設置プレス

に「クラスター」の解説があります。これに基づいて厚生労働省は動いていると思われるのですが、そこはさておき、ここにでてくる「SEIRモデル」とは何ぞや?というところからスタートします。

SEIRモデル

SEIRモデル – Wikipedia

を見ると、比較的簡単な微分の方程式です。摂動論(古いけど)をやってた自分としては、ああ、となるし、機械学習を少しかじれば、ああ、となる式でしょう。それほど難しくありません。
時間tによって、状況が変化するという典型的な式です。

難しくはないんですが、いざ数式に直すとすると結構難しそうなので、先人の知恵を辿ります。

新型コロナウイルスの流行を科学的に考えるためのヒント|ノルテ / 気象と波浪の研究者|note

上記の記事から、SEIR の意味がこれです。

  • Susceptible: 感染症に対して免疫を持たない者(無免疫者)
  • Exposed: 感染症が潜伏期間中の者(感染者)
  • Infected: 発症者
  • Recovered: 感染症から回復して免疫を獲得した者(回復者)

wikipedia の式と違うのは、短期間なので、「mは出生率及び死亡率」のmを0とみなすことができるからです。

Dispersion vs. Control からたどった先には、github の R のコードがあります。

[GitHub – HopkinsIDD/nCoV-Sandbox]

あと WHO からのデータはここです。

Situation reports

記号の意味を把握すると、先のS,E,R,Iの初期値の他に

  • β: 感染率
  • lp: 潜伏期間
  • ip: 感染期間

が必要になります。

そのまま R で解けばいいんですが、R が不慣れなので別なのがないかと探します。

感染症数理モデル事始め PythonによるSEIRモデルの概要とパラメータ推定入門 – Qiita

に python の実装があるので、そのまま流用します。

Python で SEIR モデルを動かす

python 自体も不慣れなので、コードとか変数とかはそのままなのですが、以下の3つをインストールした後に

pip install numpy
pip install scipy
pip install matplotlib

次のコードを実行します。

#include package
import numpy as np
from scipy.integrate import odeint
from scipy.optimize import minimize
import matplotlib.pyplot as plt

#define differencial equation of seir model
def seir_eq(v,t,beta,lp,ip):
    return [
        -beta*v[0]*v[2],
        beta*v[0]*v[2]-(1/lp)*v[1],
        (1/lp)*v[1]-(1/ip)*v[2],
        (1/ip)*v[2]]

#solve seir model
ini_state=[3000,0,5,0]
t_max=100
dt=1
t=np.arange(0,t_max,dt)
plt.plot(t,odeint(seir_eq,ini_state,t,args=(0.001,14,7)))

plt.legend(['Susceptible','Exposed','Infected','Recovered'])
plt.show()

パラメータの意味は、以下の通りです。

  • 初期S v[0]: 未感染者 3000
  • 初期E v[1]: 潜伏者 0
  • 初期I v[2]: 発症者 5
  • 初期R v[3]: 免疫獲得者 0
  • 感染率 beta : 0.001
  • 潜伏期間 lp : 14日
  • 発症期間 li : 7日

それっぽい数値を入れてみたのですが、あまり根拠はありません。実際は、それぞれの値は分布(分散)があるので、ランダム値でシミュレーションすることになるはずです。

意味合いとしては、閉鎖空間で3000人いたときに、初期状態で感染者が5人いたときの状況をしらべています。
感染率「0.001」の意味は、「基本再生算数:1人の感染者からうつる人数の目安となる」の R0(WHO で「1.4から2.5」)となるので

感染率 beta 
  = (初期感染者 * R0)/全体の人数
  = (5*1.4)/3000 = 0.0023

という計算となると思うんですが、よくわからないので適当にいれています。

追記:きちんと計算したものはこちら
http://www.moonmile.net/blog/archives/10384

感染率の分布を考える

実際は、感染率 beta や基本再生算数 R0 を推定するわけですが、現在のところ感染力ある程度推測されている(既存のインフルエンザよりも低い)ので、それを当てはめてみています。

ただし、インフルエンザ流行の「スーパースプレッダー」にあるように、感染はまんべんなく起こるわけではなく、とある閉鎖空間で一気に広がるであろうと想像されています。

となれば、感染率 beta には分布があるわけで、

  • とある空間では感染率 beta は限りなく 0 に近い
  • とある空間では感染率 beta は高い

というパターンになります。
今回、感染率の高い空間を「クラスター」と呼ぶわけで、それらは閉鎖空間であったり、不特定多数の人が密集している場であったりします。それらの「クラスター」同士をつなげないようにして、感染拡大を防ぐ、というのが「クラスター対策」の主旨ですね。

ひとまず「SEIRモデル」を数値計算してみたかったので、この後は感染率を分布(Θかσ)させるところへ。

カテゴリー: 開発 | 感染症数理モデルでシミュレーションする(その1) はコメントを受け付けていません

Scratch 3.0 で Web API 呼び出しの拡張ブロックを作る、の手始め

Scratch 3.0 の拡張ブロックの作り方が分かってきたので、Web API の呼び出しを作ってみる。

基本的なところは、Scratch 3.0でオリジナルブロックをつくろう – Qiita と同じで、もうちょっと先に進んでみよう、というところです。Scratch 自体が学習用なので、その目的に沿っているかどうかは分からないのですが、まぁ、ちょっとばかし無茶をやって業務で使ってみるのもアリかなぁと。「Scratch はプログラム言語なのか?」という質問が多い中で、じゃあ、実用的な業務で使うためにはこんなパターンがあるという例です。

適当な MDA ツールとして使う

ブロックを組み合わせてロジックを作る言語(ビジュアル言語とかブロックプログラミングとか)は、Scratch の他にどんなものがあるのか?というと、

なんてのがあります。この中に UML を含めてもいいかもしれません。ブロックを組み合わせて細かいロジック(加算や減算など)を組むものもあれば、ある程度コンポーネント化されたものを呼び出す MDA(モデル駆動型アーキテクチャ)的なものもあります。

Scratch の場合は、細かいロジックを組む所謂プログラム言語に属する訳ですが、手順を繋げたり条件分岐をうまく使えば MDA なツールとしても使える…と思ってみるわけです。

試してみるのは、

  • 適当な Web API を複数回呼び出す
  • Web API の戻り値で適当に分岐する
  • Web API の戻り値で適当に猫が喋る

あたりを想定して作っていきます。
テストデータの投入を自動化するとか、サンプルデータの投入あたりを考えてみます。

下準備

まずは、ローカル環境で Scratch 3.0 が動く環境を整えます。Linux 環境でやるのが望ましいのですが、Windows の WSL を使っても大丈夫です。というか、VSCode を使うと便利なので、WSL がお薦めです。

github からコードをダウンロード



$ git clone --depth 1 https://github.com/llk/scratch-vm.git $ git clone --depth 1 https://github.com/llk/scratch-gui.git

ビルド



$ cd scratch-vm $ npm i $ sudo npm link $ cd ../scratch-gui $ npm i $ sudo npm link scratch-vm

scratch-vm に拡張機能を使って、scratch-gui で UI を動かします。scratch-gui は React が使われているので、scratch-vm 内のコードを修正すると自動的にブラウザのほうでリロードが掛かります。

試しに実行

ローカル環境で http://localhost:8601/ とすれば、ブラウザで Scratch 3.0 が動く状態になります。



$ cd scratch-gui $ npm start


この状態で、ほぼ https://scratch.mit.edu/ と同じ状態になります。違いは、

  • 共有ができない
  • サーバーにコードが自動保存されない。

ことぐらいです。

ローカル環境では、「ファイル」メニューからローカルのコンピュータにコードを保存できます。この保存したファイルを本家の Scratch にアップロードすれば共有が可能になります。

ただし、今回のようなオリジナルな拡張ブロックを使っている場合は本家では動かないので、適宜ローカル環境で動かすか、社内で適当なサーバーを立てて(ラズパイ3とかでも十分です)そこにアクセスするか、という形になります。

多分、ラズパイ上に Scratch 3.0 のサーバーを立てて、そこから Arduino に接続させるとか、センサーのデータを読み取るとかするほうが PC よりも手軽かもしれません。そのあたりはおいおい模索していきます。

リモート環境で VSCode を動かす

WSL(Windows System Linux)にはリモート接続対応の VScode をインストールできます。



$ code .

WSL 上でこんな風に code コマンドを入れると、自動的に Windows 側で VSCode が立ち上がってくれます。

ドライブが共有になっているので、Windows 側で閲覧してもよいのですが、WSL 側とファイル競合が発生してまうので、リモート接続にします。ここで *.js のファイルを編集して保存すると自動的にブラウザのほうでリロードが掛かります。

scratch-vm の編集

拡張機能を「webapisample」にして作成していきます。



$ mkdir scratch-vm/src/extensions/scratch3_webapisample/ $ touch scratch-vm/src/extensions/scratch3_webapisample/index.js

scratch-vm/src/extensions フォルダーの中に、新しく「webapisample」フォルダーを作って index.js ファイルを作成します。



const ArgumentType = require('../../extension-support/argument-type'); const BlockType = require('../../extension-support/block-type'); const Cast = require('../../util/cast'); const log = require('../../util/log'); class Scratch3WebApiSample { constructor (runtime) { this.runtime = runtime; this._result = "" ; this._url = ""; this._result = ""; } getInfo () { return { id: 'webapisample', name: 'Web API Sample', blocks: [ { opcode: 'setUrl', blockType: BlockType.COMMAND, text: 'Set URL [TEXT]', arguments: { TEXT: { type: ArgumentType.STRING, defaultValue: "http://localhost:5000/api/Hello/" } } }, { opcode: 'getUrl', blockType: BlockType.REPORTER, text: 'URL' }, { opcode: 'getResult', blockType: BlockType.REPORTER, text: 'result' }, { opcode: 'callWebApiByGet', blockType: BlockType.REPORTER, text: 'Call Web API GET [TEXT]', arguments: { TEXT: { type: ArgumentType.STRING, defaultValue: "100" } } } ], menus: { } }; } setUrl( args ) { const text = Cast.toString(args.TEXT); this._url = text ; } getUrl() { return this._url ; } getResult() { return this._result ; } callWebApiByGet(args) { const text = Cast.toString(args.TEXT); const path = this._url + text ; var pr = fetch( path ) .then( res => res.text() ) .then( body => this._result = body ) ; return pr ; } } module.exports = Scratch3WebApiSample;

少し癖があるのですが、

  • getInfo 関数で、ブロックの情報を返す
  • opcode に対応する関数名を記述する
  • それぞれの関数内で Javascript で記述する

ブロックの種類にはいくつかあるのですが、

  • BlockType.COMMAND : コマンドブロック(非同期)
  • BlockType.REPORTER : 値ブロック(同期処理)

になります。Web API呼び出しでは、fetch を使うのですが、ここをコマンドブロックにすると戻り値が取れません。なので、値ブロックにして同期的に処理を行います。戻り値は fetch が返す Promise 型を使えば ok です。

Scratch 3.0の拡張機能を作ってみよう/応用 – Japanese Scratch-Wiki を参考にしてください。


   callWebApiByGet(args) {
        const text = Cast.toString(args.TEXT);
        const path = this._url + text ;
        var pr = fetch( path ) 
            .then( res => res.text() )
            .then( body => this._result = body ) ;
        return pr ;
    }

ここでは4つのブロックを作っていて、こんな感じになります。

Web API を実行する http://localhost:5000/api/Hello/ は後で、ASP.NET Core MVC で作ります。ここの呼び先は、PHP で作ってもいいし、nodejs でもいいし、Azure Functions でも構いません。

クラス内の変数の扱いは、JS なのでそれに則ります。このあたり、コード自体は Javascript なので、結構いろいろなことができます。

scratch-vm/src/extension-support/extension-manager.js のファイルに、拡張機能をインクルードするための行を追加しておきます。以下の「★」の部分です。



const builtinExtensions = { // This is an example that isn't loaded with the other core blocks, // but serves as a reference for loading core blocks as extensions. coreExample: () => require('../blocks/scratch3_core_example'), // These are the non-core built-in extensions. pen: () => require('../extensions/scratch3_pen'), wedo2: () => require('../extensions/scratch3_wedo2'), music: () => require('../extensions/scratch3_music'), microbit: () => require('../extensions/scratch3_microbit'), text2speech: () => require('../extensions/scratch3_text2speech'), translate: () => require('../extensions/scratch3_translate'), videoSensing: () => require('../extensions/scratch3_video_sensing'), ev3: () => require('../extensions/scratch3_ev3'), makeymakey: () => require('../extensions/scratch3_makeymakey'), boost: () => require('../extensions/scratch3_boost'), gdxfor: () => require('../extensions/scratch3_gdx_for'), webapisample: () => require('../extensions/scratch3_webapisample') // ★ };

最終的には id を使ったりするのでしょうが、いまはこのままで。

vscode でファイル保存して特にエラーが出なければ ok です。

scratch-gui の編集

scratch-gui では拡張機能を読み取るところを追加します。



$ mkdir scratch-gui/src/lib/libraries/extensions/webapisample

webapisample このフォルダーに2つの画像ファイルを置きます。

  • webapi.png
  • webapi-small.png

拡張機能を読み込むときに使われる画像ですね。面倒ななので字だけです(苦笑)。

scratch-gui/src/lib/libraries/extensions/index.jsx 追加の設定を記述します。



import webapisampleIconURL from './webapisample/webapi.png'; import webapisampleInsetIconURL from './webapisample/webapi-small.png'; // 省略 { name: "Web API Sample Blocks", extensionId: 'webapisample', iconURL: webapisampleIconURL, insetIconURL: webapisampleInsetIconURL, collaborator: 'moonmile', description: "You can call Web API.", featured: true, internetConnectionRequired: true, helpLink: 'http://moonmile.net/' } }

最初の import はアイコンを指定しているだけなので、直に iconURL や insetIconURL に指定してもよいでしょう。多言語化しないので、FormattedMessage を使わずに直書きしています。

ファイルを保存して、Scratch 3.0 側で拡張機能を読み込むと、オリジナルのブロックが現れます。Javascript のコードが間違っていたり、ブロックの opcode などの設定が間違っていると、拡張ブロックの部分が読み込めないので注意してください。

読み込めなかったときのデバッグ手段がないので、ちょっとずつブロックを増やしていくのがコツです。

Web API を作る

.NET Core を使ってテスト用の Web API サーバーを作ります。



$ dotnet new webapi -n hello

こんな風に hello プロジェクトを作った後に、Controllers/HelloController.cs を追加します。



using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; namespace hello.Controllers { [Route("api/[controller]")] [ApiController] public class HelloController : ControllerBase { // GET api/values/5 [HttpGet("{id}")] public ActionResult<string> Get(int id) { var text = "Hello api {id}"; System.Diagnostics.Debug.WriteLine(text); return text; } } }

数値の id を渡されたら「Hello api 100」のように返すだけの GET メソッドです。本来ならば、データベース検索をしてデータを返すところです。ASP.NET MVC の Web API は自動で JSON 形式で返すのですが、ひとまずこのままにしておきます。

もう一つ、XSS 対応をしておきます。Scratch 3.0 では http://localhost:8601/ で動くのですが、作成する Web API は http://localhost:5000/ で動くことになります。なので、クロスサイトスクリプトの実行状態になり、そのままでは次のようなエラーがでます。これは Chrome の F12 でエラー表示をしたところです。

この対策のために、Web API 側で CORS 対策をします。
Microsoft.AspNetCore.Cors パッケージを dotnet コマンドで入れた後に、



dotnet add package Microsoft.AspNetCore.Cors

Startup.cs に次の2行を追加します。



using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.HttpsPolicy; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; namespace hello { public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { services.AddCors(); // CORS 追加 services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } else { // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. app.UseHsts(); } app.UseCors(o => o.AllowAnyOrigin()); // CORS 追加 app.UseHttpsRedirection(); app.UseMvc(); } } }

これで先のエラーがなくなります。dotnet run で Web API サーバーを動かしたあとに、ブラウザで http://localhost:5000/api/Hello/100 のように確認してみてください。

実行してみる

Scratch 3.0 と Web API サーバーを起動した状態で、次のようにブロックを組んでみます。

猫スプライトをクリックすると、「カウンタ」が+1されて、Web API が呼び出されます。Web API は同期的に呼び出されるので、戻り値が「結果」に入って、猫が喋る、という簡単なものです。

内部的にはちょっと複雑な(とはいえ、Web APIを呼び出しているだけだけど)ことになっていますが、表面的にはカウンタを使って何かの「結果」を取ってきているだけです。

実際、猫をクリックすると結果がカウントアップされていくのが分かります。きちんとデータベース検索をしてやれば、IDなどを渡して Web API 経由でデータを引き出すこともできます。

今後は

fetch を使って Web API を順次呼び出せることが分かったので、

  • CRUD を揃えて、RESTful な Web API にしておく。
  • データベース検索をする
  • やり取りを JSON 形式にして、プロパティの受け渡しができるようにする

を引き続き後日。

カテゴリー: 開発 | Scratch 3.0 で Web API 呼び出しの拡張ブロックを作る、の手始め はコメントを受け付けていません

マッチ棒とゴムのトリックの問題

下記のツイートをみて、ちょうど力学の解説によいと思ったのが落とし穴であった。ので、きちんとした解答を書き直し

を見て思いついたのが、支点の移動の話で、下記な図を描いたのだが、これは間違い。

image

さきについていた、

先進科学塾@名大「遊びで探る重心の世界」2017.10.22 | ひろじの物理ブログ ミオくんとなんでも科学探究隊 https://ameblo.jp/hamgon1971/entry-12321955194.html

の補足で作ったつもりだったのだけど、上の図じゃなくて、こんな感じになる。

石で支えているときは、左のように重心が支点外側にあって力点を掛けてペットボトルを支えている。このまま石を外すと、作用点だけが残るのでペットボトルが落ちる。

ここでマッチを使って左のように重心が支点の下に来るようにずらす。そうすると、支点の直下に重心が来る(支点自体が作用点である重心を支えるようになり、作用点=力点が等しくなる)、これによって、石がなくてもペットボトルは落ちずに支えられる、という仕組み

image

マッチの動画で「不思議」に見えるのは、ここの重心のずれ(支点への移動)がさりげなく行われるので、同じ格好でもペットボトルは落ちないという不思議さがうまれるのがミソ。

だから、極端な感じで先のブログにもあるように「指一本」で支えることも可能で、あらかじめ水色のマッチ棒の部分が固定化されていれば、一点で支えられる。

image

マッチ棒とゴムでは難しいので、実際に割りばしとビニール紐でやるとこんな感じになる。テーブルの上が平たいので左に落ちないので、やや浮いた形でバランスが取れる。下にぶらさがっている Linux ペンギンはちょうどテーブルの縁の真下に来る。

image

何処で勘違いしたのだろう

ミスリードになったところは、この部分で。

image image

こんな風に取っ手のついた傘の動きを考える。

この場合、支点は傘の柄の先にあって無理矢理上から押さえつけて、傘の開くところを支えてまっすぐにしている。

これを手を離すと、傘の棒の部分が内側にずれて、重心が移動し支点の真下に来る、

image

ここに話を結び付けたかったのだけど、実は違ったということ。実は支点の先に(左側)に棒が続くかどうかの違いなんだけど、そこに引っかかってしまった、というか墓穴を掘った。うーむ。

材料工学的には片持ち梁の問題

この支点の問題なんだけど、材料工学では典型的な「片持ち梁」の問題だったりする。

片持ち梁とは?1分でわかる構造、様々な荷重による応力と例題 http://kentiku-kouzou.jp/struc-katamotiharitoha.html#targetText=%E7%89%87%E6%8C%81%E3%81%A1%E6%A2%81%E3%81%AF%E3%80%81%EF%BC%91,%E8%87%AA%E7%94%B1%E3%81%AB%E3%81%97%E3%81%9F%E6%A2%81%E3%81%A7%E3%81%99%E3%80%82

片持ち梁の場合、一方が固定点で片方が自由点。自由点のほうに何かをぶら下げると、応力かかるという問題。先のマッチ棒と傘の重心移動は、もういっぽうも自由点なのだが、ちょうどその中間を考えるとこんな図になる。

片持ち梁は壁に固定する(壁自体が剛体だから)のだが、釘みたいに壁に打ち込むタイプはこんな感じに力が働く。釘の上としたに力が働くわけで、接着剤の場合は下の面積(はがれる)が問題だし、コンクリート打ち込みの場合は上の力が問題(上がひび割れる)になる。

image

また、中間となる支点に大きな力が掛かるので、ここがひび割れる。支点のひび割れに対しては力を分散するために梁を使うか、R を付ける。この R 部分がおもしろくて、こんな風に黄色の部分を余分につける。

image

片持ち梁でもそうなんだが、この直角の部分の角には応力集中が働くので R を付けて応力分散をする、さらに支えともなる。という面白い特性がでてくる。

さらに先の「量産~」でツインドリル制作の時に聞いたのだけど、プラモデルのような場合でも同じように応力集中が掛かるので、こわれないように R を付ける。この R は、さきの棚のような場合には後付けになるのだが、プラモデルの型抜きのようなものは、金型のほうを「削る」という後から加工でいけるという特性がある。金属の型って、一発でできることは少なくて、少しずつ削っていくのだが、

  • 金属の型のほうを削ると、材料のほうの厚みが増して強度があがる(安全性があがる)
  • 最初は直角であっても R を付けるときは、金属の型を削るだけなので、修正が簡単。

という加工工程としても、後から修正するほうが「安全に倒れる」という興味深い話があるので、そのあたり支点の移動とか応力の分散とかの話に繋げたかったというのがあるわけで。

このあたり、物理屋さんとしては、

  • 思考実験をして仮説を出す
  • 仮説を確認/証明するために実際の実験をする
  • 実験が仮説と違っていたら、仮説を疑う(物理法則は変わらない)

を繰り返す。

これはプログラムのバグ取りとか性能検証とかも同じで、ある程度仮説出して進める。実測データがいくつか取れるが、それが仮説とあっているか検証する。たまに仮説とあっていない場合(思うように性能があがらないとか、本来のバグとは違った箇所を直しているとか)があるので、無理に仮説に合わせようとしないで、一度保留にして仮説に立ち返る、というループになる、という話,

を忘れがちになるので忘備録としてメモしておく。

カテゴリー: 雑談 | マッチ棒とゴムのトリックの問題 はコメントを受け付けていません

Windows 7 で Scratch から micro:bit を扱えるようにする

学童のプログラミング教室で、Minecraft on Scratch から子供の興味を引きはがすべく、micro:bit を 5個(増税前、消費税8%の駆け込み)購入しました。

実はスイッチサイエンスさんはキャッシュレス還元に対応したそうなので、10/1 以降に購入したほうがお得だったわけですが。まあ、いいや、勢いで送料無料になる1万円まで大人買いです。

※ああ、結果だけ欲しい方は、一番最後にジャンプするといいです.

学童で子どもに試してみる

プログラミング教室をやっている学童に先に請求してもよいのですが、ここは実験も兼ねて自腹で購入。うまくいけば後で、欲しい子には2,000円也で購入してもらうか、学童に請求を上げるかというところなのですが。

あえなく「玉砕」です。

まず、数あるプログラミング教室の中で、私が行っているところは、

  • 小学3-6年生が10人ちょい雑多に集まっている感じ。
  • 予算の関係上、中古 ノート PC の Windows 7 を使っている。
  • 場所が共有スペースを使っているので、デスクトップ PC は置けない。
  • 有線 LAN が使えず、無線 LAN(私物の Pocket WiFi)を使っている。
  • ノート PC に Bluetooth が付随していないものが多い。
  • 中古のノートPCなので、USB が 1個しか生きていないものが多くて、USB ケーブルのマウスと付け替えないといけない。
  • そもそも、micro:bit(mbed) への HEX ファイルのドラッグ&ドロップが子供には難しい。

このプログラミング教室は、3年前から始めたのですが、プログラミングを教える…ってのは雑多な環境では難しかったので、「Scratch で遊ぶ」にシフトしました。いは、Scratch で作られているゲームならば、なんでも ok ってことで、ファミスタもどきとか青鬼もどきとか、いろいろ流行りがあって、今はマインクラフトもどきなのです。
ちなみに、ゲームばかりやっている子ばかりではなくて、Scratch でゲームを自作している子もいます。

  • ゲームを自作している子には、適宜質問に答える&適宜手伝う。
  • ゲームをしている子は、攻略法は友達同士で話し合ってね

というルールでやっています。学童の目的として「安全に子供を預かる」が有線なので、プログラム自体を教えるってのは二の次なのです。とはいえ、漠然と遊ばせるだけはつまらないので、毎回プリントを配るし(1回300円也を徴収しているので)、それなりに「パソコンに慣れる」ことを目的としています。

と、いう状況はさておき、プログラミング環境としてはあまりリッチな環境ではありませんが、そこは工夫次第というところです。

Scratch から micro:bit を操作する

micro:bit を操作する方法は2種類あります。

MakeCode を使ってプログラミング

https://makecode.microbit.org/

こんな感じでブロックを使ってプログラムをして、micro:bit に流し込みます。ダウンロードした後に HEX ファイルをドラッグ&ドロップする方法と、あらかじめ micro:bit とリンク(たぶん、BLEを使っている)させておいて「ダウンロード」ボタンを押したら直接流し込んでくれる方法です。

手元の PC でやると、この自動流し込みが便利なので操作的にはさほど気にならないのですが。Bluetooth の付いてないデスクトップPCとか、古い Windows 7 のノートPCだと結構な手間です。

あと、Scratch に慣れていると、この

  • プログラムをコンパイルして、マイコン(micro:bit)に流し込む

という流れが難しかったりします。そのあたりは、電子工作で Arduino を使っていれば慣れるので(というか慣れないといけない)ので、それはいずれやるつもり。

Scratch 3.0 から直接 micro:bit を操作

https://scratch.mit.edu/

もうひとつ、Scratch 3.0 の拡張機能を使う方法です。Scratch 3.0 では、あらかじめ micro:bit に scratch-microbit-1.1.0.hex なファームを書き込んでおいて、BLE 通信をしながら操作する方法です。これだと、いちいち micro:bit に書き込む必要がなくて、Scratch の操作だけで micro:bit を扱えます。

micro:bit と BLE 通信で連携をするので、

  • micro:bit のAボタンを押したら、猫に喋らせる
  • Scratch 猫をクリックしたら、micro:bit の LED を光らせる

という動きが簡単にできます。これだと、物理的なものを「プログラミングで操作する」というのが直感的にわかっていいです。内部は、ややこしいことになっているのですが。

Scratch で micro:bit を操作するためには、条件があって、

  • BLE 接続できること
  • Scratch Link を動かしておくこと

があります。micro:bit と BLE 通信をするので、Buetooth が必要なのはいいのですが、さて、Scratch Link がちょっと癖ものなのです。
Scratch Link の動作条件が、

  • Windows 10 以降
  • macOS

ということになっていて、Windows 7 では動かない。何故?ってことになります。

scratch-link
https://github.com/LLK/scratch-link

理由は、Scratch Link のコードを見るとわかります。Windows の場合、UWP で使われている Bluetooth モジュールを使っていて、これが Windows 10 以降しか入っていないんですよね。Windows 8 が出た頃に、BLE 通信が流行った時代があって、そのときに Windows 7 で動かそうとして悪戦苦闘した覚えがあります。結局 BLE 通信は無理なので Bluetooth のシリアル通信にしましたが。実は、Scratch Link 内部ではシリアル通信も対応しているのですが、インストール環境が Windows 10 以降になってしまっているので、これでも Winodws 7 は使えないのです。まあ、そのときは自前ビルドをするわけですが。

Scrach 3.0 のコードは Github で公開されているので、

の3つから調べることができます。scratch-microbit-1.1.0.hex のコードは見つからなかったのですが、まあ、これは BLE のペリフェラルなところなので省略してもokでしょう。

ざっと、調べたところこんな感じです。



Scratch on Browser WebSocket ^ | JSON-RPC v WebSocketServer JSONRPCWebSocket + didReceiveCall Scratch Link BLESession + DidReceiveCall + OnValueChanged ^ | BLE GATT v BLE micro:bit
  • Scratch 3.0 で WebSocket を使っている
  • Scratch Link は WebSocketServer で待ち受け
  • Scratch 3.0 – Scratch Link の間は JSON-RPC で通信
  • Scratch Link と micro:bit は BLESession で BLE 通信

そうなると、Scratch Link の JSON-RPC で受けているところを適当に WiFi に切り替えてやって、ラズパイや適当な Windows 10 を挟み込んだプロキシを作ればいけそうですね。

と思って、Scratch Link のコードを .NET Core で書き換えようとしたところ、Scratch 3.0 -> Scratch Link な URL ってどうなっているのか?と思い至りました。いやいや、WebSocket を使ったことがなかったので。

Scratch Link – Japanese Scratch-Wiki

を改めてみると、『そのため、Scratchはlocalhostに直接アクセスできないため、device-manager.scratch.mit.eduに接続する。』という一文があります。たしかに、scratch-vm のコードを検索すると、この URL が書いてあって、直接ローカルなPC(localhost とか 127.0.0.1 とか)には接続していないんですね。

なるほど!WebSocket って localhost が使えないのか!ってことでした。
思い込みで、localhost しか使えないのかと思っていたのですが、実は localhost「は」使えないという落とし穴が(苦笑)あったのですね。
なので、Scratch 3.0 は、拡張機能で WebSocket を使うたびに device-manager.scratch.mit.edu を呼び出して DNS で 127.0.0.1 を返して貰っています。

hosts を変更する

となれば、話は簡単です。
いちいち、ローカルホストに接続するために device-manager.scratch.mit.edu を呼び出しているということは、他の PC を呼び出したい場合は device-manager.scratch.mit.edu を通す必要がない、ということです。

なので、実現したい環境として、

  • Scratch 3.0 が動いている Windows 7
  • micro:bit と接続している BLE ありの Windows 10

という別々の環境を作った場合、Windows 7 から Windows 10 の Scratch Link への通信に切り替えてやればよいわけで、

  • Windows ならば、C:\Windows\System32\drivers\etc\hosts
  • Linux ならば /etc/hosts

を書き加えます。



192.168.1.28 device-manager.scratch.mit.edu

「192.168.1.28」なところは、Windows 10 のある PC の IP に書き換えてください。こうすることで、device-manager.scratch.mit.edu への呼び出しが偽装されて、micro:bit に繋がっている Scratch Link(Windows 10 あるいは macOS) へ接続されます。

2以上繋がっている場合は、こんな風に並ぶので名前で使い分ければよいでしょう。

scratch-vm のほうを書き換える

なお、もう一つの方は、scratch-vm にある WebScoket の接続先を書き換えます。

scratch-vm/scratch-link-websocket.js at develop · LLK/scratch-vm

scrach-gui/vm/link をあれこれやっているのは、自前でオリジナルなブロックを創ったり、Android の Firemate に繋げたりしたいので、こっちのほうはいずれ試してみる予定。

カテゴリー: 開発 | Windows 7 で Scratch から micro:bit を扱えるようにする はコメントを受け付けていません

Scratch から micro:bit を操作する Scratch Link を自前ビルドする

マインクラフト on Scratch から子供たちを脱却すべく(別に脱却する必要もないのだけど)、micro:bit を5個購入しました。

なんで5個なのかというと、スイッチサイエンスさんで10,000円以上だと送料が無料になるからです。消費税8%のうちの駆け込み需要かと思いきや、スイッチサイエンスさんは実はキャッシュレスの軽減税の対象になったそうなので、どちらが安いのか分からないのですが。まあ、5個購入しました。

左に移っているのは chibi:bit で、以前購入したものです。確か、猫ボードあたりと揉めたときに記念に買ったものです。まだ、micro:bit に BLE が技適が通っていなくて Bluetooth のチップを独自で乗せて独自に技適を通したもの…だったハズです。実は、本国(英国)から送って貰ったものが手元にあるはずなのですが、行方不明で。

それはさておき、micro:bit を使います。

micro:bit をブロックプログラミングする

プログラムしましょう | micro:bit

micro:bit は Scratch のようにブロックプログラミングができます。内部は Google の Blockly がベースになっていて Microsoft が開発というハイブリッドな環境が話題になりました。

ここのサイトは、micro:bit の mbed な機能を使って、USB 接続したドライブに HEX ファイルを落とし込むという方法でプログラムを変更します。Arduino IDE や mbed を使っていると、なじみのある方法です。

実は、ブロックだけじゃなくて、Python や JavaScript も使えるので、キータイプをしたい場合にはこっちのほうを使うといいかもしれませんね。特に JavaScript のほうはブロックにしてから JavaScript のコードを表示できるので、コードの比較ができて便利です。

Scratch から micro:bit を操作する

もうひとつのほうは、Scratch の拡張機能を使って micro:bit に Bluetooth 接続をする方法です。

動作環境が、

  • Windows 10 あるいは macOS であること
  • Windows 10 側に Scratch Link が動作していること

と若干敷居が高いのですが、micro:bit が Bluetooth 接続できます。micro:bit にはあらかじめ、”Scratch micro:bit HEX” をインストールしておいて、Scratch Link 経由で micro:bit に接続します。HEX ファイルは Scratch – micro:bit でダウンロードができます。ちなみに、chibi:bit のほうは、https://t.co/KiQDkQIgw3 からダウンロードが可能です。

Scratch 側で micro:bit のブロックを作って、micro:bit のボタンや加速度センサーによって、Scratch 側で動きを制御できます。

このあたりは、micro:bit サイトの MakeCode よりも試行錯誤ができて便利です。

?

仕組みはどうなっているのか?

さて、ここまできたら、どういう動作になっているのか?できれは自作でハックをしてみたいのがプログラマの性です。いずれは、Scratch 3.0 のほうに独自の拡張ブロックを入れて、ということも視野にいれて、

を参考にして、独自の Scratch 3.0 環境を作ります。
Ubuntu on Windows を立ち上げて、以下でインストールします。



$ git clone --depth 1 https://github.com/llk/scratch-vm.git 
$ git clone --depth 1 https://github.com/llk/scratch-gui.git

後は、ビルド


$ cd scratch-vm 
$ npm i 
$ npm link 
$ cd ../scratch-gui 
$ npm i 
$ npm link scratch-vm

あとは、npm start すれば、http://localhost:8601/ で接続できるようになります。


$ cd scratch-gui 
$ npm start


micro:bit 拡張機能のコードは以下にあります。



scratch-vm/src/extensions/scratch3_microbit/index.js

接続方法として

Scratch 3.0 <=> Scratch Link <=> micro:bit

になるわけですが、

  • Scratch 3.0 と Scratch Link の間は、JSON
  • Scratch Link と micro:bit の間は BLE

です。
拡張機能を自作したい場合は、JSON のところをフックすればよいので、適当な拡張機能をコピーすればなんとかできそう。

BLE 通信のほうは、実は Scratch Link は以下で公開されています。

LLK/scratch-link at master

このコードを改変してビルドをすれば、独自に BLE をフックできるハズです。
ざっと中身をみてみると、UWP の BLE を使っていて GATT で通信させています。GATT を使っているので、Windows 7 とかでは動かないわけです。
現状はラズパイでは動かないようですが、macOS のコード(swiftだけど)をうまく修正すれば、macOS 以外でも動くかもしれません。

自前の Scratch Link をビルドするには、ちょっとコツがあります。というか、対象の開発環境が古いみたいで Visual Studio 2019 ではビルドができません。
.NET Framework のバージョンを最新(v4.7.2)に上げた後に、エディタで以下の修正をします。

Windows/scratch-link/ScratchLink.csproj

  • Windows.winmd ファイルの参照先を自前のものに変えておく。

- <hintpath>C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.16299.0\Windows.winmd</hintpath>
+ <hintpath>C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.18362.0\Windows.winmd</hintpath>

最後の scratchVersion.targets を削除する



- <import project="..\scratchVersion.targets">

本来は、scratchVersion.targets の git あたりを修正するのがよいのですが、ひとまず参照自体を削除。バージョンが 0.0.0.0 になるので、ちょっとまずいのですが。

この修正が終わると、無事ビルドが通って

  • 自前の Scratch 3.0(scratch-gui, scratch-vm)を起動
  • 自前の Scratch Link を起動
  • micro:bit に BLE 接続する

ことができます。

カテゴリー: 開発, Scratch | Scratch から micro:bit を操作する Scratch Link を自前ビルドする はコメントを受け付けていません

掌握術のコールド・リーディングの話を少し

プログラミングは技術的な側面を押し出す理系的な面が多いけれど(この「理系」もかなり語弊があるが)、なにかと政治的な面に首を突っ込まないといけないことが多い…と言いますか、政治的な話でプロジェクトが潰されて現場のプログラマが被害を被るということが多々あります。

実は、アジャイル関係の教本には「政治的なことは別なところで解決してくれ」とはじめにと書いてることもあり、政治的な話を避ける傾向があります。が、ケント・ベック氏が10数年前に来日時に話していた通り「私たちの頃は、社会不適合者がプログラミングをしていたが、これからは社会的なコミュニケーションが重要視されると思う。娘の姿をみているとそう思う」なのです。ときに、XP がペアプログラミングで相互コミュニケーションを重要視したように、何かを技術的な側面だけで解決できるとは限らない、ということです。まあ、私自身も、いまとなっては「古い人間」なので、政治的な問題は苦手なところが多くできるだけ避けてはいるのですが、そのあたりは、技術者らしく政治的なものも技術的側面で解決するという脇道も考えるのです。

さて、某K議員の発言もあり、政治的な発言が「空疎」であると同時に、なにか深い意味がありそうなという「深読み」をする面もあり、いったいどちらなのだろうか?と思うところもあるでしょう。そのあたりの結論は脇に置いて(その問題は私の関知するところではないので)、もっと某K議員の天然ではないところに注目してみます。

目の前の人の共感を得る方法

会話というものが、瞬時的に1対1で行われる以上、相手からの好意を引き出すというのは円滑なコミュニケーションをする上で重要なことです。円滑なという言葉を使いましたが、狡猾なという言い方に変えても同じです。要は、相手に嫌悪感を与え防壁を作るよりも、うまく壁を取り除き(自分の壁は置いたままで)、自分の言葉刷り込ませるというテクニックを使います。

相手が好意を持つ(嫌悪感を持たない)ようにさせるためには、「あなたのことは特別です」という意図を伝えるのがベターです。一般的には、相手の目を見て会話する、という方法がとられますが、複数名に話しかけると同時にひとりに話しかけるということも可能です。

  • 会話をするときに、数秒間だけ相手のほうに顔を向ける
    → いわゆる、アイドルを見て「私だけを向いた!」という奴ですね。
  • 事前に調べた、その人しか分からない(と思われる)情報ををチラ見させる。
    → あなたのことを知ってますという方法
  • 会話の中で知った、その人の言葉を使う
    → あたなの言葉を私はきちんと聞いていますというアピール

人間も動物なので、自分だけが特別が扱いされるとうれしいものです。「うれしい」=警戒心緩むということですね。警戒心が緩むと、相対的に猜疑心が減るので、心の隙間に入りやすくなります。

ただし、よく営業トークである、相手に YES で同意するというのは、以前はよかったのかもしれませんが、最近は「胡散臭いやつ」や「なんでも YES と言えばいいと思っている奴」に見えるので、やめたほうがベターです。だんだん、人々は賢くなってきていますからね。優しい雰囲気は、老人にはいいのかもしれませんが。

この好意を与える方法の逆を取って、嫌悪感を与えるという方法も使えます。いわゆる、スケープゴート(生贄)をグループの中に作って、スケープゴート以外で団結させるという技ですね。先の好意を寄せるこの逆をすれば、グループの中に生贄を作れます。

  • その人からの質問をはぐらかして、他の人の質問を受け取る。
  • その人からの意見を取り上げた上で、別の人の意見に同意する。

これは某都知事がやっている方法で、たぶん無意識でやっています。この手の会話術は無意識でできる人(おそらく育ちだと思う)と、無意識ではできない人がいます。結果的には、無意識でできる人が、政治家向きなのですが(心理的なストレスが少ないので)、これを意識的にやる(会話をしているときに、裏で二重に会話を構成する)人は、政治家以外にもちらほらといるので注意が必要です。

相手の情報を事前チェックする

昔(30年前位だろうか)の営業としては、事前チェックは当たり前のことだったし、必須であったと思うのですが今はどうなんでしょう?昔はインターネットがなかったので、相手の情報を内密で得るのはなかなか困難でした。新聞なり図書なりを利用したり、事前に廻りの人に聞いたりするしかなかた訳で、コールド・リーディング(事前に知った相手の情報を利用する)の手法は占い師の秘匿の手段でもありました。

ただし、今だと事前に相手の情報を得るのは結構簡単です。

  • Google で相手の名前を検索する
  • Google で相手の会社を検索する、地図を見ておく
  • 商品情報や研究内容を検索する
  • 類似品の情報を検索する
  • 技術要素の用語を検索しておく

のように、相手の名前や社名で検索すれば結構でてきます。これは完全に事前ではなくても、会議中のトイレの中でも検索できるわけで、相手にとって「よく知っている人」に見えるようになります。つまり、警戒心を下げられるわけです。

私の場合はあまり得意ではないのですが、相手の会社の地図から、食べ物情報を検索して「あの店はおいしいですよね」と雑談するのもよい方法です。ええ、やる過ぎると胡散臭くみられるので、注意が必要ですが。

会話中に相手の情報を利用する

もうひとつの掌握術として、リアルタイムに会話をしているときに、相手の情報を使って相手の警戒心を下げるという方法もあります。ホット・リーディングと呼ばれますが、これも単なる会話術にひとつですね。

その場で知った相手の情報を活用するだけでなく、「相手に自分が何かを知っているように思わせる」という手法があります。これが冒頭に書いた、某K議員の話であって、

  • 何か言葉を使っているが「空疎」な言葉しか吐かなくて馬鹿なやつ
  • 何かグローバルな言葉を使って「意味深」な頭の切れるやつ

という感想が同居します。これ、同じ言葉を同じシチュエーションで使っても、受け取る側で二面的に取られるということです。そして注意したいのは、どちらも会話を発している本人とは関係ないところで起こる現象です。

image

さんざん、マスコミでの情報の切り取り問題が起こっているので、発言者から発せられた「発話A」が、それぞれの受け取り方で異なることが分かると思います。これは意図的な切り取りがなくても発生します。例えば、同じ会議室で、発言者が「発話A」を発したとしても、聞いている人が別であれば、別の発話を受け取ります(これ、音波的には同じもなのか?という問題もあるけど、まあ、音波であっても違いますよね)。

ただし、発話Aを受け取った人は、微妙に異なる「発話A’」と「発話A’’」を受け取りますが、この差異はあまり大きくありません。マスコミやツイッターなどの意図的な切り取りは別なのですが、同じ場所で同じ発言を聞いていれば、多少は差異はあるけれども、ほぼ同じものを着ている。あとから「発話A’」と「発話A’’」を比較しても「発話A」を再現できる程度に正確に聞き取れているでしょう。

しかし、これを理解するための「解釈」の段階になるとことなります。それぞれの「知識B」と「知識C」が大きく異なるため、理解するための「解釈 A’+B」と「解釈 A’’+C 」は異なる可能性が高いのです。これが同じ発言を聞いても「空疎」と「意味深」が同居する理由です。

まあ時には、「空疎」だけど「意味深」という形で同居する解釈もできるので、それは頭の中で「知識B」と「知識C」を切り替えて2つの解釈を割り出す方法です。

これを発言側から見れば、相手の知識Bと知識Cに向かって「解釈が異なる」ことを利用します。つまり、相手に「知識B」があると仮定したうえで、漠然とした発話Aを発します。知識Cの人にとっては訳がわからないのですが、あらかじ知識Bの人は「受け答え」をします。この受け答えを以って、相手が「知識B」をもっていることを発言者は知ることができるのです。この問答は、試験官と面接者の関係に似ています。異なるのは、発言者Aは、あらかじめ「知識B」の全体をしらなくても、それとなく知識Bが回答させられるように、発言Aを「漠然と」言うということです。そして、発言者Aは、まんまと知識Bの概要を得ることができます。

一見、ややこしいように見えますが、よく親が子供に対して「今日、何かあった?」という聞くよりも、「今日の国語のテストはどうだった?」とカマを掛けるのと同じです。国語のテストがなければ、子供は「国語のテストなんかないよ、何言ってんの」と言うでしょうが、ちょうど国語のテストがあれば、隠していたテストの結果を出してくるでしょう。親の側では、国語のテストがあってかどうかを知らずに、国語のテストの結果を得られます。

こんな感じなのが、ホット・リーディングの会話テクニックなのですが、このあたり先天的に(というか家系的に?)無意識でやっている人たちもいるので、対抗手段を講じるのは必要でしょう。私的には無意識でやっているのは進化論のひとつだと思うのですが、その話はまた別の機会に。

カテゴリー: 雑談 | 掌握術のコールド・リーディングの話を少し はコメントを受け付けていません

ラズパイ3 と Wii リモコンをつなげる

台風が近くまで接近しているので、非常に眠いので眠気覚ましに。

世の中は任天堂スイッチの世界なので、Joy-Con で操作することが多いと思うのですが、Joy-Con はちょっと高い。正規版だと 8,000円位しますね。互換機?(バイブレータがないらしい)の場合だと、もうちょっと安いみたいなのですが、まあ、手元に Wii コントローラがあるし、試しにつなげてみようというところです。

以前、ラズパイに Wii コントローラをつなげようとしたとき、古い Wii リモコンだとうまくいくのですが、新しめの Wii リモコンプラスだとペアリングがうまくいきません。Bluetooth 側のプログラムを改変すれば、接続はできるのですが、それがいいのかどうか不明だったので放置状態でした。

bluetoothctl と xwiimote を使う

ラズパイ3 に xwiimote を入れて使います。
ラズパイ3 の Raspbian には既に bluetooth に接続するための bluetoothctl があります。



sudo apt install bluez

した後で



bluetoothctl

を実行します。プロンプトが出るので、



power on scan on

で接続先の Bluetooth 機器を探します。

このときに、Wii リモコンの裏側の赤いボタンを押して、接続待ち状態にしておくと、Nintendo RVL-CNT-01-TR のデバイス名が出てきます。ここに出てくる ID を使って、



pair 9C:E6:35:04:51:4A connect 9C:E6:35:04:51:4A trust 9C:E6:35:04:51:4A

して接続をします。

これで、Bluetooth 接続状態にしておいて、xwiishow コマンドを使います。



sudo apt install xwiimote

してインストールした後に、



xwiishow 1

で Wii リモートの操作画面を表示させます。

A,Bボタンの操作や、加速度センサー、IRセンサーの値が表示されています。

詳しい使い方は、下記を参照

XWiimote – ArchWiki

どうやって Wii リモコンの処理ををするのか?

Linux なのでデバイスはファイルとして開かれるので、/sys/bus/hid/devices で調べられるそうです。



pi@raspi3:~ $ ls /sys/bus/hid/devices 0005:057E:0330.0002 pi@raspi3:~ $

たぶん、xwiishow のあたりから API が出てると思うのだけど、これは後で。

コードがここで公開されています。
GitHub – dvdhrm/xwiimote: Open Source Nintendo Wii Remote Linux Device Driver https://github.com/dvdhrm/xwiimote

PC の場合は、WiimoteLib というライブラリがあるそうです。

Siv3DでWiiリモコンを使う – Qiita

カテゴリー: 開発 | ラズパイ3 と Wii リモコンをつなげる はコメントを受け付けていません

ラズパイ以外でもROS2してみよう(PINE A64編)

去年の年末 年末なので ROS を調べてちらほらと | Moonmile Solutions Blog 以来さわっていない、ROS2 なのだが、通信まわりだけでも再構築しておこうと思った記録を残しておきます。

ROS2 のインストールに関しては WEB で色々調べると出てくるのだけど、ROS(いわゆるver.1)と、新しい ROS2 が混在してしまって、ややこしいことになっている。インストールと最初の諸々に関しては、次の本を買ったほうが時間の節約になります。

ROS2ではじめよう 次世代ロボットプログラミング
https://www.amazon.co.jp/dp/4297107422

Kindle 版だと3,000円ちょっとだし、半日時間をつぶしてあれこれ調べるよりも(実際に潰してしまった…)、この本を買ったほうが早いでしょう。

とは言え、最初のインストール部分だけ抜き出せば、Raspberry Pi 3にROS2をインストール – RT Robot Shop Blog にある通り、


export CHOOSE_ROS_DISTRO=dashing sudo apt install curl curl http://repo.ros2.org/repos.key | sudo apt-key add - sudo sh -c 'echo "deb [arch=amd64,arm64] http://repo.ros2.org/ubuntu/main `lsb_release -cs` main" > /etc/apt/sources.list.d/ros2-latest.list' export CHOOSE_ROS_DISTRO=dashing sudo apt update sudo apt install ros-$CHOOSE_ROS_DISTRO-ros-base sudo apt install python3-argcomplete sudo apt install python3-colcon-common-extensions

で、最初のインストールまでは完了です。これで、ラズパイ3と Windows 10 上の Ubuntu(WSL:Windows Subsystem for Linux) の両方でインストールができます。

公式は ROS Index: Installation になるので、何か困ったことが起こったら、ここを見るとよい。英語だが、コマンドが羅列されているだけなので、なんとかなるでしょう。

あと、ラズパイ3 への Ubuntu は 64bit 版が必要なので、http://cdimage.ubuntu.com/ubuntu/releases/bionic/release/ubuntu-18.04.2-preinstalled-server-arm64+raspi3.img.xz を使うことになります。

通信だけ試してみる

ROS2 には、ロボットアームのエミュレーションとか各種センサーのコンポーネント化とか、GUI も含めてロボット開発には必要な機能が満載なのですが、私の場合、通信部分だけが使いたいので、通信だけやっていきます。
最終的にはロボットアームの制御と、3Dプリンタ、PLAN2 の ROS2 化までやりたいのだけど、(何度も失敗しているので)小さく始めるということで。

ROS2 は、Publisher/Subscriber方式で通信をしていて、日本語で言えば「出版-購読者」のパターンです。GoF で言えば「Subject/Observer」だったりしますね。ROS1 のときは仲介サーバーが必要だった(ハズ)のですが、ROS2 は P2P で繋がるようになっていてシンプルになっています。

ROS2 をインストールして最初にやることは、ターミナルを2つ開いて、

Publisher側


ros2 topic pub /chatter std_msgs/String "{data: Hello world.}"

Subscriber側


ros2 topic echo /chatter

で動かすことです。

※ 実際は、環境変数の設定があるので、以下を動かしてパスを通す。あとデモ用のパッケージをインストールする


echo "source /opt/ros/$CHOOSE_ROS_DISTRO/setup.bash" >> ~/.bashrc source ~/.bashrc
  • Windows 上の ROS2(実際は WSL上の ROS2)
  • PINE A64 上の ROS2

とで通信ができることが分かる。この2つは同じネットワーク上で使われていて、それぞれの IP は「どこにも設定していない」のがミソで、仲介役があって何か IP とかを送っているわけではない。これはかなり便利。

PINE A64 の Ubunut で試す

PINE A64 ってのは、ラズパイ3のようなマイコンボードで、ちょっと大きめの中華ボード。秋月で 3,000円位で買える

ボード自体が大きいのと、USBが2個しかないのが難点なのだけど、

  • ラズパイよりも価格が安い
  • ラズパイ3よりも性能がいい(らしい)

ところがある。まあ、Android を動かしたかったので、PINE A64 を購入したのだけど、今となっては Android のバージョンが古くなってしまったので、ちょっと放置状態。

PINE A64 も armbian に Linux OS がある。

Pine64 – Armbian

これは、最初から 64bit 対応になっているので、64bit が必須となる ROS2 がそのまま使える。と言う訳で、Ubuntu 環境で arm64 を用意すれば、

  • ROS2 が使える
  • .NET Core 3 が使える

という形になっている。たしか、React Native も 64bit 環境が必須だったと思うので、PINE A64 や ラズパイの Ubuntu 環境でも動くでしょう。

お次は、C++ で ROS2 のパッケージを作って動かしてみましょう…ってのは後日。

カテゴリー: 開発, ROS | ラズパイ以外でもROS2してみよう(PINE A64編) はコメントを受け付けていません

リモートデスクトップでラズパイに接続する

Windows からラズパイにリモート接続する方法はいくつかあって、

  • VNC を使う
  • Xming を使う
  • リモートデスクトップを使う

という方法があります。昔から、定番は VNC でラズパイ側に VNC サーバーを起動させておいて、Windows で VNC Viewer を使うという方法ですね。

比較的安定しているし、LAN 内でも結構遅くて苦痛なのですが、画面全体を操作する場合は仕方がないということで使っています。

Xming のほうは、Windows 版の X サーバーを入れて操作する方法で、Xming X Server for Windows 日本語情報トップページ – OSDN かなりバイナリが古いのですが、Windows 10 上でも軽快に動きます。xterm だとか、X Window に対応しているソフトをラズパイ側に入れておくと動きます。

で、実は、昔から Windows のリモートデスクトップを使う方法があったのですが、結構遅いし、日本語入力が打てないとかいう問題がありました(ラズパイ側に wnn とか入れればいい?)。ですが、今だと軽快なスピードで動きます!何が変わったのか?単に CPU スピードが速くなったのか?
少なくとも VNC Viewer だと遅くて辛いのですが、リモートデスクトップだと全然問題ありません。

インストールは簡単で、ラズパイ側に xrdp を入れるだけです。


sudo apt install xrdp

Windows からリモートデスクトップで接続すると、xrdp のログイン画面が出ます。

session は X.org のままにしておいて、ログインすれば ok です。

画面はちょっともたつきますが、設定とか Scratch ぐらいならば全然 ok ですね。ssh でつなげてコンソールで設定するのもいいんですが、GUI があると楽です。

特にラズパイの場合は、HDMI 接続せずに LAN ケーブルつけて放置(あるいは WiFi 接続のみ)することが多いので、ちょっとした GUI の設定が必要なときに便利です。

ちなみに、Ubuntu にも xrdp を入れると普通に接続できます。

Ubuntu(うちのは 18.04)に xrdp を入れるだけでリモート接続できるのでお手軽です。Ubuntu のほうは日本語入力が使えます。VSCode も軽快に動きます。

カテゴリー: 開発 | リモートデスクトップでラズパイに接続する はコメントを受け付けていません

俺のOrange Pi One に .NET が(以下略

Raspberry Pi 3 で .NET Core 3 が動くならば、ラズパイ互換の Orange Pi でも動くだろう、と思って確認してみたのがこれです。

結論から言えば、前回 と同じように、.NET Core 3 preview をインストールすると、ラズパイと同じようにビルド&実行ができるようになります。

Orange Pi One とは何か?

Orange Pi One ってのは、こんな感じのラズパイ互換機です。

ラズパイ3だと、USBコネクタが4つあったり、BluetoothやWiFiが乗っていたりするのですが、Ornage Pi One は、USB コネクタが1個だけなのと、BluetoothやWiFiがありません。ちっとばかし不便な気もするのですが、ラズパイ3が5,000円強かかるのに対して、Orange Pi One は1,000円位で済みます。

orange pi one – Orangepi

Orange Pi One H3 512MB Quad core Support ubuntu linux and android mini PC-in Demo Board from Computer & Office on Aliexpress.com | Alibaba Group

以前は、公式?な販売サイトが Ornage Pi のサイト内にあったのですが、今は Aliexpress の中にあります。正規がここらしいので、郵送諸々は問題ありません。中国の深圳から中国郵便で送られくるので、約1週間位で届きます。長くても2週間弱ですね。

OS は Armbian を使う

Orange Pi シリーズはラズパイよりも多種多様なものがあって、用途によって性能が低くても安いのから、ちょっと性能が高くて高めのものまで様々です。OS は、Linux 系のものが動くのですが、公式からダウンロードするとバージョンによって起動しなかったり、そもそもダウンロードができなかったり(リンク先が切れている場合がある)するので、Armbian のものを使います。
Armbian は、ARM 系のマイコンボードに OS をビルドしてくれている有志の集団です。いわゆる、ラズパイ互換の中華ボードは、大抵揃っているので Armbian からダウンロードして使うとよいです。

Orange Pi One だと以下からダウンロードができます。

Orange Pi One – Armbian

最近は Ubuntu と Debian を利用できるようになっています。

この armbian で配布しているディストリビューションは、自前でビルドすることもできて、手順などが Building Armbian – Armbian Documentation に書かれています。ビルドしたことはないんですが…いずれ。

.NET Core 3

.NET Core 3 preview 版を入れて、dotnet new mvc -n web で作成して dotnet run したところまで。


見るとわかるのですが、Orange Pi One のメモリは 512MB しか(?)ありません。まあ、昔の Linux に比べれば断然大きいのですが、動画のエンコードとか機械学習の用途には無理ですね。さて、これは何に使うか。

カテゴリー: 開発, NET Core | 俺のOrange Pi One に .NET が(以下略 はコメントを受け付けていません