includePathが見つからない(Intel Mac)他

久々にIntelMacとM1MacでVScode環境でc++コンパイルしようとしたらいくつかのエラー発生。IntelMacは問題が二箇所で、M1Macは一箇所だけでしたが

— Intel Mac —

<問題1:includePathが見つからない>

以下を参考にパスを追加

https://jpdebug.com/p/151056

% g++ -v -E -x c++ –

で検索されたパスをc_cpp_properties.jsonに追記してコンパイルはできるようになったけど波線(つまり見つからないエラー)は消えないので、以下を追加

c_cpp_properties.jsonの、

“compilerPath”: “/usr/bin/clang”,

“compilerPath”: “/usr/bin/g++”,

に変えたら解決したようだ、これは即ち

% where g++ 

/usr/bin/g++

で示されるパスですが

<問題2:無限にXcodeコマンドラインツールをインストールしろメッセージ>

Xcodeコマンドラインツールをインストールしろと怒られて、何回インストールしても直らない

https://qiita.com/arks22/items/bb1a70a4803881c4e4e1

が該当していて、エラーメッセージの中に確かに解決案が提示されてます

~~~~~

Please ensure Xcode packages are up-to-date — try running ‘xcodebuild -runFirstLaunch’.

~~~~~

で以下の実行で解決したようです

% xcodebuild -runFirstLaunch

どこかのOSのアップデート、恐らく至近、で問題が出るようになったんでしょう

 

— M1Mac —

MacBook Air(M1)ではg++の版数を再指定(古い版数でコンパイルされたので)しなければいけなかったし、これもアップデート影響なのか

感覚的にはかりそめの解決のような気もするけれども、元々開発環境とはそういうものだろう

 

admin

co2センサー(MH-Z19)のキャリブレーション

測定値が、風通しの良い場所でも800ppmとか高い値になっていて、場所を変えてもダメだったのキャリブレーションしてみた。

https://github.com/UedaTakeyuki/mh-z19/wiki/CALIBRATION-&-detection-range

Pythonライブラリ関連の情報の中にキャリブレーションツールも用意されているのでそれを使いました。

co2センサーはシリアルでRaspberry PIとつながっているのでroot権限で実行しないといけませんが、

$ sudo python -m mh_z19 –zero_point_calibration

Call Calibration with ZERO point.

で実行できました。多少低すぎの感もありますが、いずれまたズレていくんじゃないか(以下の③によって)と思います。

ソースを見ると、以下で規定されるゼロキャリブレーション方法の②のコマンドによって実行しています。

https://www.winsen-sensor.com/d/files/MH-Z19B.pdf

ゼロキャリブレーションには① ハード的にピンを一時的に短絡、② コマンド送信、③ 自動キャリブレーションの三つの方法があるとなっていますが③の有効/無効化もコマンドで対応できるのでライブラリから指定できるようになっています。

また、コマンドパラメータに-hでヘルプ、何も付けないと辞書型({“co2”: 414} のように)で測定値が返ります。

ゼロキャリブレーション以外にスパンキャリブレーションというのもありますが、これはスケール精度、つまり1000ppmや2000ppmの値の倍率(スケール)精度用ですが、正確な1000ppm環境など作れないから省略。

P.S. 2022/9/18

限りなく外気に触れる場所で測定値の収束時間を見てみました。

 

保存していた部屋(おそらくco2濃度1000ppm近く)から無人の部屋の窓を開けて、窓辺に放置して時間経過と測定値。おそらく最初は部屋のガスが取り込まれて高い値を示していますが、徐々に大気の値に近づいていきます。おおむね20分放置しろとデバイスのマニュアルに書かれてますから、初期値が高かったらその程度の放置時間は必要そうです。

 

admin

 

iPad Air(5代目)

素のiPadも購入後3年経過して、ssd(32GB)も七割ぐらい消費、それ以外の性能(scribbleが反応遅いとか)あるので買い替え。

期待値は以下の3点、

① Apple siliconの処理性能、特にneural engineに期待

② SSD容量、まあ64GBあれば3年持ちそう

③ Apple Penci 1の充電方法がイマイチだし、新機能の消しゴムにも期待

Pencil使うのは画面が指紋だらけになるのが嫌だからというのも大きな理由

 

本体に遅れて、ペンとケースも届いたので必要なものは揃いました。旧iPadからの移行はApple ID/MicroSoft/Googleのログオンするだけで完了です。旧iPadのデータ消去はMacBookと比べて初期化手順は簡単でした。画像とか音声の大容量ファイルは無いから。

<第一印象>

・Scribbleは明らかに高速になってます

・Pecil 2の充電楽チン(本体の電池容量はiPadより小さいんだ)

・本体の画面サイズ拡大して画面も美しい

ということで、良い買い物でした。

 

admin

Matter.js(物理計算エンジン)

物理計算エンジンで軽量で動くものとしてMatter.jsがあります。古典物理法則に則って物体の動きを、衝突、摩擦、重力などの要素を考慮して計算しようとするとそれらを一から作り上げるには労力ですが、それらの機能を提供した「世界」を簡単に作り上げて、物体の動きをシミレーションできるものです。

公式のサイトは、

https://brm.io/matter-js/

Getting started

https://github.com/liabru/matter-js/wiki/Getting-started#usage-example

Demo

https://brm.io/matter-js/demo/#stats

———————————————————

Tutorialのサンプルに、以下の機能を付け加えています。

① マウスコントロール追加

② 背景を透過にする(デフォルトは真っ黒)

③ オブジェクトに重力、反発係数、初速などを設定できるようにした

コードを有効にするには、Matter.jsをコピーしていずれかのディレクトリに配置してコードから呼び出すようにします。

GitHubのコードリンクは、

https://github.com/chateight/electron/tree/master/matter_case

になります。

物理計算エンジンはUnityなどにももちろん使われているわけですが、JavaScriptで「割と簡単」に扱うには良い素材ではないでしょうか。

P.S. 2022/9/16

・全てのボールに初期速度をインターバルタイム毎に与えるように変更

四角形と円とで2つの大まかなグループ分けで動くようになりました

 

admin

electron-packagerで作成したアプリを立ち上げるとエラーになる

タイトル通りですが、アプリ起動時に以下のようなポップアップが表示されます。アプリそのものは動くのですが、以下の例だとelectron-logファイル見つからないよと言ってます。

じゃその、electron-logファイルどこになるのかと言うとnode_modulesディレクトリに存在しています。全体のディレクトリ構造は以下の通り。

エラーはelectronディレクトリでmove_catディレクトリのアプリをパッケージにしようとした時に発生しています。

で、move_catディレクトリの必要ファイルをelectronディレクトリにコピーして、electronディレクトリの上の階層からelectron-packgerで作成すると問題なく作成できました。当然**-arm64は上の階層に作成されます。

つまり、アプリ関連ファイルとnode_modulesディレクトリは同じ階層にないとパッケージに組み込まれないと言うことですね。

 

admin

 

ScratchのようにJavaScriptで制御してみる

Scratchもブロック言語をJavascriptで解釈して実行しているようなので、ScratchでできることはJavascriptでもできるし、おそらく逆も真。

と言うことで基本的な要素だけ盛り込んだサンプルを作ってみました。

ソースコード、package.jsonはとりあえず無関係でhtmlとjsファイルの二つだけです。ネコスプライトと背景画像はIP関連が不明なのでアップしてません。

<html>

https://github.com/chateight/electron/blob/master/index.html

<java script>

https://github.com/chateight/electron/blob/master/control.js

動かしてみると、

start/stopボタンでイベントリスナー登録していますが、startボタンで関数実行時にリスナー解除して、複数押しができないようにしています。もし複数押しを可能にするとネコスプライトの動きが加速されます。複数のスレッドが走るような状況になるんでしょう。

// constnt & variables
let xmin = 0;       // set moving area
let ymin = 0;        
let xmax = 800;        
let ymax = 350;        
let x = 1;          // position integer
let y = 1;
let x_px = "";      // position string "px"
let y_px = "";
let dir_x = 1;      // moving direction
let dir_y = 1;
let int_id;         // setInterval ID
//
// interval timer start function
const tmr = () => {
    int_id = setInterval(move,20);                  // "int_id" for clear "clearInterval"
    start.removeEventListener("click", tmr);        // stop the listener
}
//
// move function
function move(){
    const pos = document.querySelector(".img1");         
    if(dir_x === 1) {
        x_px = x.toString() + "px";                   
        pos.style.left = x_px;
        x += 5;
        if(x >= xmax) {
            dir_x = 0;
            pos.style.transform = "scale(-1, 1)";       // reverse the sprite
        }
    }
    if(dir_x === 0) {                   
        x_px = x.toString() + "px"; 
        pos.style.left = x_px;
        x -= 5;
        if(x <= xmin) { 
            dir_x = 1; 
            pos.style.transform = "scale(1, 1)"; 
        } 
     } 
     if(dir_y == 1) { 
         y_px = y.toString() + "px"; 
         pos.style.top = y_px; 
         y += 5; 
         if(y >= ymax) {
            dir_y = 0;
        }
     }
    if(dir_y == 0) {     
        y_px = y.toString() + "px";
        pos.style.top = y_px;            
        y -= 5;
        if(y <= ymin) { 
            dir_y = 1; 
        } 
     } 
} 
// 
// start from here 
let start = document.querySelector(".start"); 
let stop = document.querySelector(".stop"); 
start.addEventListener("click", tmr); 
stop.addEventListener("click", () => clearInterval(int_id));

P.S. 2022/9/9

コードが冗長で見苦しいのでコンパクト化して、なおかつスプライトの向きを上下移動でも変えてみました、GitHubにのみ反映です。

Electron配下のディレクトリに作成しているので、デスクトップアプリでも動作できます。

 

admin

Wine

Electronで各プラットホーム向けの配布用のアプリを作成するのにWineのインストールが要求(具体的にはWindows用のはず)されますが、じゃWineって何?なのかというとWindows用のAPIを提供して、Windows OS以外でWindows用のアプリケーションを完全互換では無いけれども動かせるオープンソースのアプリケーションのようです。

MacbookでElectronからアプリ起動してもWineが立ち上がるようなので、使い方はいまいちリサーチ必要。

 

admin

Electronのイントロ

初めてのelectron、ほぼ以下のリンクのままですが

https://www.materializer.co/lab/blog/66

electronって何なの? => “Build cross-platform desktop apps with JavaScript, HTML, and CSS”

とelectronのトップページに出ています。

Node.jsがインストールされている前提で、

npm(Node.jsのパッケージ管理)でelectronをインストール、ただし既にインストール済みでした。VScodeあるから?

% npm -v

8.18.0

・実行は作成したプロジェクトの一つ上のディレクトリで、例えば以下のディレクトリ構成でfirst_porjectを実行するならば、

/electron/first_project

/electronディレクトリでコマンド実行

% electron first_project

・ログの取り方はelectron-logをインストールしてファイルに書き出すようにする

% npm install electron-log

こんな感じで使います、

const log = require(‘electron-log’);

log.info(‘Hello, log’);

ログファイルの場所は、

# cat ~/Library/Logs/electronのプロジェクト名/main.log

・配布用の実行ファイル作成はelectron-packager使いますが、なぜか”Error: Cannot find module ‘electron-log’”と言うエラーメッセージウインドーが表示されます。

アプリの実行結果は、こんな感じで間伸びした画面、ほぼ中身ないから。

 

<Node.jsについての説明>

Node.jsはJavaScript用のサーバー機能を提供、electronではChromium(以下の通り)と一緒に使います。

“Node.js® is a JavaScript runtime built on Chrome’s V8 JavaScript engine.”

https://nodejs.dev/en/learn/

 

P.S. 2022/9/10

electronのインストールはローカルインストールにすべきだと

-gオプションでインストールすると将来版数がアップされた時に互換がなくなると管理できなくなるからローカルでインストールすべきと。

・ローカルインストール

% npm install -save-dev electron

・実行

% npx electron <ターゲットディレクトリ>

npxはローカルインストールしたモジュールを実行するためのコマンドです。

 

admin

『今時のJavaScriptを知るための本』ワンパス終了

およそ一月半前に購入の書籍、一通り読了、読むんじゃなくて自分でコード書いてみるのがポイントですが。

https://isehara-3lv.sakura.ne.jp/blog/2022/07/24/今時のjava-scriptを知るための本/

個人的にはHTMLをクライアント側で処理すると言う使い方よりは、サーバーサイドあるいはデスクトップアプリでの使い方に興味があります。

それらの使い方では動作環境としてはNode.jsになるんでしょうけれども、そもそもVScodeもNode.js使っているのは初めて知りました。従ってデスクトップアプリならElectron(開発はGitGub)の選択になるのでしょう。

Node.jsの拡張パッケージ使えばTypeScriptも扱えるようですね。

 

admin

関数宣言より関数式か

Javascriptは他の言語に比べると、ちょっと仕様が違うよねと言うところがありますが、それはwebページ向けに使われ始めたと言う歴史的なものがあるだろうと思う。そのためか感覚的にはPHPにも似たところがあるようにも思う。

ところでJavascriptには関数宣言と関数式がありますが、どちらかと言うと関数式の方が使われるらしい。

関数式はhoisting(関数を使う前に宣言しなくとも呼び出せる)が出来ないことによってバグの余地が少なくできる(変数や関数の宣言を先頭でまとめてやることを強制できる)と言うのが理由のようです。

以下の例でも、”move1()”以下のスクリプトを”const move1 =・・・”の前に配置すると実行できませんからhoistingは無効になってます。

例えば、move2()は以下のように関数宣言で記述しても結果は同じだろうけども、関数式の方が変数宣言としての統一性はあるように思えるから。

function move2(){ moveElement( () => {
    const mov_to = document.querySelector(".title2");    
    mov_to.after(src);
})};
function moveElement( callback ) {              // works as a Promise factory
    return () => new Promise( resolve => {
        setTimeout(() => {
            callback();
            resolve(); }, 3000);
        }); 
}

const src = document.querySelector("#source");

const move1 = moveElement( () => {
    const mov_to = document.querySelector(".title2");    
    mov_to.prepend(src);
});

const move2 = moveElement( () => {
    const mov_to = document.querySelector(".title2");    
    mov_to.after(src);
});

const move3 = moveElement( () => {
    const mov_to = document.querySelector(".wrap");    
    mov_to.append(src);
});

const move4 = moveElement( () => {
    const mov_to = document.querySelector("li");    
    mov_to.after(src);
});


move1()
.then( move2 )      // move2 ~ move4 returns Promise instance too
.then( move3 )
.then( move4 );

本来的にマルチプロセスができない、今のJavascriptで非同期処理を実現するためにはPromiseの役割は大きいだろうから、標準で使われるオブジェクト。

 

admin