AliExpressで卓上丸のこ盤を買った

AliExpressで卓上丸のこ盤を買ったんですが、いい感じの品だったので紹介です。

www.aliexpress.com

買ったのはこれです。 1週間くらいで届いてわーおってなりました。AliExpress Standard Shippingの本気を見た感じがありますね。

f:id:shiker:20210310174322j:plain これくらいの箱で届きました。

f:id:shiker:20210310174327j:plain 内容物です。見にくいですが、細かい方の歯は既に取り付けれてます。 これの他に、使い方が書かれた紙が1枚ぺらっと入っていました。

商品ページの内容物には鋸歯は二つしか書いて無かったんですが、取り付け済みの含め三つ入ってました。PCB用、木材用、プラスチック用だそうです。

左のDCアダプタには出力調整用のスライダがついていて、回転速度を調整できます。コンセントプラグはアースが無いタイプですね。

そして、AliExpressではよくあることですが、商品ページに掲載されている写真と実物が微妙に異なります。

(商品ページより)

f:id:shiker:20210310174325j:plain

実物には歯を収納する機能がついていました。UP-DOWNと刻印されている穴にレンチを差し込み回すことで、歯を出し入れできます。使わない時はしまっておけるので実際便利です。

中身はこんな感じです。

f:id:shiker:20210310180037j:plain

配線も割としっかりしている印象です。

歯を丸いやつにして、とりあえずPCB基板を切ってみました。きれいに切れています。触っても滑らか。切るときのキーンっていう音はかなり大きいですが、この辺はまあHozanのやつとかでも変わらない気もしますね。

f:id:shiker:20210310182500j:plain

まとめ

PCB切ってみただけですが、値段の割に使いやすいです。コンパクトなのも良い。 $50くらいで買えるので、電鋸難民の方は買ってみてはどうでしょうか。

IntelliJ IDEA用のProcessinngテンプレートを作った

Processing便利だけど標準IDEは使いにくいよねということで書きました。

IntelliJを使いたい

Processingの標準IDEは環境構築が簡単なところはいいのですが、中規模以上のコードを書こうとすると辛いところが色々出てきます。
コード補完がいまいち、自動カッコ閉じの融通が聞かない、クラスが増えるとタブがカオス、etcetc...

この辺はProcessingをJavaのライブラリとして使い、Java用のIDEを使うことである程度解消できます。
そこでJavaIDEであるIntellJ IDEAを使いたいのですが、毎回ライブラリの設定とかするのも面倒です。

ということで、Processingのプロジェクトテンプレートを作りました。
以下のリンクからダウンロードできます。
作成時のIntelliJのバージョンは2019.3.1 Community版です。

drive.google.com

念の為書いておくと無保証です。
Processingのjarとかの再配布はライセンスざっと見る感じ大丈夫そうなんですが、問題ありそうなら教えて下さい

テンプレートに含まれているもの

ライブラリ設定

ProcessingCoreの他にsvg, serial, pdf, net, dxfなどの基本的なライブラリも含んでいます

実行構成

標準IDEのようにワンボタンでビルド・実行できます

クラス作成テンプレート

新しくクラスを作成したときに、PAppletインスタンスへのimport static文を追加します
標準IDEのようにProcessingの命令はどこからでも呼び出せるようになってなってないので、PAppletクラスのメソッドを呼び出す必要があります。
流石に全てのクラスに毎回インスタンス渡すのは面倒なので、staticなフィールドをおいてそれを参照するようにします。苦肉の策感...
P5.ellipse(50, 50, 100, 100)みたいに呼び出すことができます。


導入方法

 IntelliJのトップ画面にあるConfigurationからzipのままインポートすれば良いです。
 f:id:shiker:20200202153637p:plain:w500
 インポート後はユーザー定義のところにテンプレートが追加されます。
 f:id:shiker:20200202153742p:plain:w500


あとがき

この記事の下書き書いてた時はJavaで書くとラムダ式が使える!とか書いてたんですけど、寝かしている間にJava11に対応したProcessing4のα版が出てしまった...
github.com



MacにImagemagickをインストールする

MacImagemagickを入れたので書きました。

環境

MacOS: Mojave 10.14.6
HomeBrew: 2.1.15

zsh使ってます。bashでも多分同じ。

Homebrewを入れる

既に入っている場合は飛ばします。

brew.sh
HomebrewはMacOS用のパッケージ管理ツールです。少しコマンド打つだけで必要なもの全部インストールしてくれるので便利です。入れましょう。

ターミナルで

$brew --version
Homebrew 2.1.15
Homebrew/homebrew-core (git revision f8f21; last commit 2019-10-18)
Homebrew/homebrew-cask (git revision 3d08b; last commit 2019-10-18)

とか打てば入っているかチェックできます。
(実際に打つ必要があるのは$付いている行のみで、文頭の$は入力しません)

インストールする場合は

$/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

です。
少し時間がかかるのでコーヒーでも飲みながら待ちましょう。

Imagemagickを入れる

$brew install imagemagick

でインストールできます。
終わったあと

$convert -version
Version: ImageMagick 7.0.8-68 Q16 x86_64 2019-10-07 https://imagemagick.org
Copyright: © 1999-2019 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP(3.1)
Delegates (built-in): bzlib freetype heic jng jp2 jpeg lcms ltdl lzma openexr png tiff webp xml zlib

でバージョンが返ってくればインストール完了です。

バージョン6のImagemagickを入れる場合

上のでインストールするとバージョン7以降のものが入ります。6->7で色々とコマンドが変わっているので、6の方入れたいという人は以下の手順です。

#既にバージョン7インストール済みの場合のみ
$brew unlink imagemagick


$brew install imagemagick@6
$brew link --force imagemagick@6


$convert -version
Version: ImageMagick 6.9.10-66 Q16 x86_64 2019-09-23 https://imagemagick.org
Copyright: © 1999-2019 ImageMagick Studio LLC
License: https://imagemagick.org/script/license.php
Features: Cipher DPC Modules
Delegates (built-in): bzlib freetype jng jp2 jpeg lcms ltdl lzma png tiff webp xml zlib

imagemagick@6で指定することでバージョン6の方がインストールできます。
そのままだとパスが通らずCommand Not Foundとか言われてしまうので、brew linkでリンクを繋ぐ必要があります。
既にバージョン7の方がインストールされている場合は先に7の方とのリンクを解除します。

ちなみにimagemagick@6とimagemagickが逆にすれば6->7に戻せます。

$brew unlink imagemagick@6
$brew link imagemagick

あとがき

勢いで書いたので間違ってたらコメントください...

M5StickCの6軸入力から姿勢を求める(カルマンフィルタ編)

この前のMakerFaireTokyoでM5StickCを買ったので試してみました。
6軸センサの入力からX軸とY軸の角度を求めます。

MPU6886

M5StickCには6軸センサが載っています。
古いロットのものはSH200Qで、新しいロットのものにはMPU6886が搭載されているようです。
自分が買ったのはMPU6886のロットでした。

M5ロゴを正面にした場合、上がY軸の+、右がX軸の+、手前側がZ軸の+方向です。

M5.MPU6886.Init();

で初期化して

M5.MPU6886.getGyroData(&gyroX,&gyroY,&gyroZ);
M5.MPU6886.getAccelData(&accX,&accY,&accZ);

のように変数をポインタで渡すことでデータを取得できます。

getGyroDataやgetAccelDataはセンサの分解能設定によるスケール補正をかけてくれるので、ここで取得できる値の単位はdegree/sとG(≒9.8m/s^2)です。

Arduino用ライブラリの少し前のバージョンではMPU6886がMPU6866になっていたとかなんとか。

ジャイロに関しては平面に置いても0から少しずれるので、オフセット取って補正したほうが良さそうです。


カルマンフィルタ

難しくてちょっとわからない他のブログなど見ると詳しい解説がたくさん出てくるので、ここには詳しく書きません。

ノイズを含まれている複数のセンサからの入力を組み合わせ、現在の状態を推測することができるフィルタです。


今回はライブラリを使いました。
github.com
Arduinoのライブラリマネージャからインストールできます。

Kalman kalmanX;
Kalman kalmanY;

kalmanX.setAngle(getRoll());
kalmanY.setAngle(getPitch());

のようにインスタンスを作り初期角度を設定し、

kalAngleX = kalmanX.getAngle(roll, gyroX, dt);
kalAngleY = kalmanY.getAngle(pitch, gyroY, dt);

加速度から得られるX軸Y軸の角度、角加速度(degree/s)、前回呼び出してからの経過時間を渡せば、勝手に計算してくれます。便利。

プログラム

ということでできたプログラムがこちらです。
Arduinoです。

起動時にセンサのズレを補正するためのオフセットを測定しています、
カルマンフィルタを使っているので、補正必要ないかも。

実機で動かしてみるとかなり正確です。45度に傾けるときっちり45度近くの値が表示されます。

#include <Kalman.h>

#include <M5StickC.h>

//x, y, zの順
float acc[3];
float accOffset[3];
float gyro[3];
float gyroOffset[3];

float kalAngleX;
float kalAngleY;


Kalman kalmanX;
Kalman kalmanY;

long lastMs = 0;
long tick = 0;

void setup() {
  M5.begin();
  M5.Lcd.setRotation(3);
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setTextSize(1);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.println("    X       Y       Z");
  M5.MPU6886.Init();

  M5.Lcd.setCursor(0, 60);
  M5.Lcd.println("Calibrating...");
  delay(500);  
  calibration();

  M5.Lcd.setCursor(0, 60);
  M5.Lcd.printf("%7.2f %7.2f %7.2f", gyroOffset[0], gyroOffset[1], gyroOffset[2]);
  M5.Lcd.setCursor(0, 75);
  M5.Lcd.printf("%7.2f %7.2f %7.2f", accOffset[0]*1000, accOffset[1]*1000, accOffset[2]*1000);
  
  readGyro();
  kalmanX.setAngle(getRoll());
  kalmanY.setAngle(getPitch());

  lastMs = micros();
}

void calibration(){
  //補正値を求める
  float gyroSum[3];
  float accSum[3];

  for(int i = 0; i < 500; i++){
    readGyro();
    gyroSum[0] += gyro[0];
    gyroSum[1] += gyro[1];
    gyroSum[2] += gyro[2];
    accSum[0] += acc[0];
    accSum[1] += acc[1];
    accSum[2] += acc[2];
    delay(2);
  }
  gyroOffset[0] = gyroSum[0]/500;
  gyroOffset[1] = gyroSum[1]/500;
  gyroOffset[2] = gyroSum[2]/500;
  accOffset[0] = accSum[0]/500;
  accOffset[1] = accSum[1]/500;
  accOffset[2] = accSum[2]/500 - 1.0;//重力加速度1G
}


void loop() {
  // put your main code here, to run repeatedly:
  readGyro();
  applyCalibration();

  float dt = (micros() - lastMs) / 1000000.0;
  lastMs = micros();

  float roll = getRoll();
  float pitch = getPitch();
  
  kalAngleX = kalmanX.getAngle(roll, gyro[0], dt);
  kalAngleY = kalmanY.getAngle(pitch, gyro[1], dt);

  //20回に1回だけ描画
  tick++;
  if(tick % 20 == 0){
    tick = 0;
    draw();
  }
  
  delay(2);
}


void draw(){
  M5.Lcd.setCursor(0, 15);
  M5.Lcd.printf("%7.2f %7.2f %7.2f", gyro[0], gyro[1], gyro[2]);
  M5.Lcd.setCursor(140, 15);
  M5.Lcd.print("o/s");
  M5.Lcd.setCursor(0, 30);
  M5.Lcd.printf("%7.2f %7.2f %7.2f", acc[0] * 1000, acc[1] * 1000, acc[2] * 1000);
  M5.Lcd.setCursor(145, 30);
  M5.Lcd.print("mg");

  M5.Lcd.setCursor(0, 45);
  M5.Lcd.printf("%7.2f %7.2f", kalAngleX, kalAngleY);
  M5.Lcd.setCursor(140, 45);
  M5.Lcd.print("deg");
}


void readGyro(){
  M5.MPU6886.getGyroData(&gyro[0], &gyro[1], &gyro[2]);
  M5.MPU6886.getAccelData(&acc[0], &acc[1], &acc[2]);
}

void applyCalibration(){
  gyro[0] -= gyroOffset[0];
  gyro[1] -= gyroOffset[1];
  gyro[2] -= gyroOffset[2];
  acc[0] -= accOffset[0];
  acc[1] -= accOffset[1];
  acc[2] -= accOffset[2];
}

float getRoll(){
  return atan2(acc[1], acc[2]) * RAD_TO_DEG;
}

float getPitch(){
  return atan(-acc[0] / sqrt(acc[1]*acc[1] + acc[2]*acc[2])) * RAD_TO_DEG;
}

おわりに

M5StickCでカルマンフィルタを使う記事があまりなかったので書いてみました。

いろいろ調べていたらMadgwickフィルタなるものも見つけたので今度試してみたいです。
カルマンフィルタよりも処理が軽いとかなんとか?