メカナムホイールの設計

Robomasterを見てメカナムホイールを使いたくなり設計してみた。
projectrm.niwakasoft.jp

とりあえず第一弾は、このような感じで完成した。

設計にあたり、以下に気をつけた。

  • なるべく、手持ちの3Dプリンタ(ANYCUBIC MEGA-S)と、近所のホームセンターで購入できるもので組む。
  • サブホイールのグリップ素材として、燃料ホース(10cmが20円程度)を利用する。近所では、内径x外形で 6x3・7x4・8x5・9x6・11x7・ 12x8・ 13x9・16x12といろいろ揃う。
  • サブホイールのシャフトとして、ステンレス棒(1mが数百円)を利用する。

復習も兼ねて、サブホイール部分の作り方をまとめておく。

メカナムホイールの設計方法 by ohguma

(1)まずホイール径を決める。
f:id:ohguma:20190819004758p:plain

(2)ホイール厚を決める。両端にオフセット平面を準備しておく。
f:id:ohguma:20190819004806p:plain

(3)サブホイール用の傾斜平面を準備する。原点の軸でなく、(1)のホイール径のスケッチの直径部分の直線を軸とすれば、作成した傾斜平面ともとの平面の原点が揃い、作業しやすくかった。角度は45度。
f:id:ohguma:20190819004656p:plain

(4)サブホイール径は、使用するグリップ素材に依存する。今回は外形x内径が9x6mmの燃料ホースを採用。サブホイールはホイール外形に合わせてラグビーボール状に径が変化するが、異なる径のホース(外形8mmと9mm)を使いそれを再現する(つもりだったが、ある程度伸びるので1種類のホースで実装した)。
f:id:ohguma:20190819004700p:plain

(5)ホイール径を越さないい程度に、押し出し量を目視で調整。
f:id:ohguma:20190819004703p:plain

(6)サブホイールの軸はホームセンターにある2mmのステンレス棒を使用。切断にはニッパーでなく、クリッパーを使用。

f:id:ohguma:20190819004712p:plain

(7)サブホイールの端を基準にオフセット平面作成。
f:id:ohguma:20190819004717p:plain

(8)サブホイールの支えを押し出し。
f:id:ohguma:20190819004721p:plain

(9)サブホイールと支えを、円状配置でコピー。
f:id:ohguma:20190819004725p:plain

(10)履歴を戻り、支え部分の形状を変え、各サブホイールごとの支えが重なり、結合できるようする。
f:id:ohguma:20190819004729p:plain

(11)支えのみを結合し、(2)のオフセット平面を使って、はみ出す部分を切り取り。
f:id:ohguma:20190819004734p:plain
(12)サブホイールを非表示にして、支えを結合
f:id:ohguma:20190819004738p:plain

(13)適当に面取り。印刷時に下側になる面は、面取りして天井を作らないようにする。斜めのオーバーハングする壁ならサポートなしで印刷できる。
f:id:ohguma:20190819004742p:plain

(14)適当に軸受等を作成。
f:id:ohguma:20190819004745p:plain

(15)コピーして、メインホイールの裏表を揃える
f:id:ohguma:20190819004751p:plain

(16)サブホイールを表示して全体を確認。
f:id:ohguma:20190819004754p:plain

反省

サブホイールのシャフトをサンドイッチして支えるようにしたが、ホイールの組み立てがとても面倒だった。
メインホイールの外側から長いネジを通して、反対側をナット等で固定する方式を推す。

micro:bitでサーモグラフィーを作ってみた(さらに更新)

見栄えのする表示デモは未だ思いつかないが、電源投入時にぼんやり明るくなるようにしてみた。

makecode.microbit.org

micro:bitでサーモグラフィーを作ってみた(更新)

温度の表現方法を思いつき、プログラムを更新した。
ohguma.hatenablog.com

これまでは、

  • 20~30度を青~赤で(色相の変化 240~0、彩度99、輝度10)

表現していたが、以下を追加し、表現の幅が広がった。

  • 30度超~30度を赤~白で(彩度の変化 99~0、輝度10)
  • 20度未満~10度を青~黒で(輝度の変化 10~0、彩度99)

makecode.microbit.org



あとは、電源投入時に見栄えのする表示デモを時間ができたら作る予定にしておく。

TJ3Bのシリアルを無線化(再)

本ブログの記事には嘘がないよう注意していますが、勘違い等で誤ったことを記載する可能性があります。
本ブログの記事の内容を元に発生した損害については一切の保証は出来ません。
ご利用の際はご自身で十分に検証の上、自己責任で対応してください。


せとうちオープン2019」でシリアルの無線化について質問いただいたので、改めて無線化に挑戦してみる。
ohguma.hatenablog.com


以前のブログ記事で使ったモジュールは発見できたが、ICソケットはなくなっていた。
f:id:ohguma:20190612001316j:plain
同じモジュールはまだ秋月で扱いがある。

他に必要なものは、28ピンのICソケット、分圧用の1KΩ・2.2KΩの抵抗各2個、ユニバーサル基板等。


まずは、秋月のモジュール取扱説明書と「ダウンロード | 株式会社ダイセン電子工業」からTJ3B組み立て説明書を用意し、回路を確認する。

秋月のモジュールで使われているRN-42は電源等3.3Vで扱うが、TJ3Bは5V。
モジュール取扱説明書によると配線用のJ1,J2,J3に5Vの電源用の端子がないが、USB接続時にUSBの5V(VBUS)から3.3Vを供給するレギュレータが載っていることが分かるので、そのVINにTJ3Bの5Vをつなぎ、3.3Vを得る。


また、TJ3B側が出力、モジュール側が入力となる箇所は抵抗で分圧して、5Vの信号が概ね3.3Vになるよう調整する。


手元にあるモジュールでの接続は次のようになった。
f:id:ohguma:20190615081818j:plain
f:id:ohguma:20190615080728j:plain


ICソケットの金具とモジュールをはんだ付けする。このタイプのICソケットならば、足から押し込むと金具を外せる。ソケットの外側が溶けないよう、金具を浮かせて作業した。CPUの足が入るように、なるべく薄くはんだ付けした。。
f:id:ohguma:20190615065258j:plain

ユニバーサル基板上にモジュールと分圧用抵抗を配線して、ICソケットとも接続する。
f:id:ohguma:20190615065759j:plain

TJ3B内蔵のシリアルポートを無効化すべく、ICソケットの17,18,28ピンは足を外に曲げておく。
f:id:ohguma:20190615070248j:plain

ICソケットとモジュールがつながったらTJ3BのCPUを戻す。
f:id:ohguma:20190615071350j:plain
f:id:ohguma:20190615071501j:plain


TJ3Bの電源をONにすると、異常なければモジュール上の緑LEDが点滅する。
PCでBluetoothを有効にして、接続し、COMポート番号を確認する。
C-Styleの通信設定でCOMポート番号を選択、もしくは手打ちし、センサモニタを開いて、有線ケーブルと同様に各センサの動きが確認できれば、作業終了。
f:id:ohguma:20190615120357p:plain

せとうちオープン2019

「せとうちオープン2019」

参加した選手、スタッフ、メンター、保護者の皆様、お疲れ様でした。
いろいろな人と交流もでき、大変楽しかったです。

6月8・9日に広島市で開催された「せとうちオープン2019」の様子など紹介。
公式戦では参加資格のないOBや大人も参加できるオープン大会で、私も「ワールドリーグサッカー ライトウェイト」にチーム「何時方向」で参加させていただいた。
rcjj-hiroshima.com

3Dプリンタ製のオムニホイールはいくつか質問も頂いた。
f:id:ohguma:20190609103124j:plain


1日目は通常のロボカップジュニアのルールのリーグ戦。
プログラムの理屈は分かっているつもりだが、サッカーの戦術や、試合の準備がまだまだ未熟であることを痛感した。
順位はこんな感じで現役選手に敵わず。
f:id:ohguma:20190608173828j:plain

一人チームの運営で写真はほぼ取る間がなかったので、様子は他の参加者のブログ等に期待し、1日目の集合写真。
f:id:ohguma:20190608171143j:plain



2日目は「せとうちオープン」恒例のサッカーBigField。
今回はA・Bの2チームに別れ、

  • 1チーム 5台。Aチームは白テープ、Bチームは緑テープで色分け。
  • 前半10分、ハーフタイム5分、後半10分。ハーフタイムでの交代はOK。
  • オープン、ビギーナークラスは1台以上参加させる。
  • 故障、アウトバウンズは30秒の退場。カウントは各自で行う。(ビギナーはアウトバウンズなし)

という条件で3試合が行われた。私はBチームに参加し、各試合の前半で出場した。

以下、各試合の様子をスマホ動画で。
なお、試合参加中の前半は車載、後半は手持ちで撮影。

全体を通してボールにはまま絡むことができ、むちゃくちゃ面白かったです。

第1試合

▼第1試合前半

せとうちオープン2019 2日目 第1試合前半

第1試合前半は、開始から1分経つ前に相手ゴール前から真っ直ぐバックしてオウンゴールしてしまう大失態(回り込みをキャンセルしたプログラムを書き込んでいた)

▼第1試合後半

せとうちオープン2019 2日目 第1試合後半

ファイナル

また、予定の3試合が終了した時点で、選手から全台参加で試合をしたいとの提案があった。選手から審判の募集も行われ、それに応える審判も多数いたため、夢の11対11サッカーが実現した。

せとうちオープン2019 2日目 ファイナルその1


せとうちオープン2019 2日目 ファイナルその2


せとうちオープン2019 2日目 ファイナルその3

Wordpress Yahoo!地図対応ショートコード

Google Map回避のため。

/**
 * Yahoo!地図対応ショートコード
 *
 * [map id="map1" w="600" h="300" z="16" address="住所" marker="yes" infowindow="吹き出し"]
 * [map id="map1" w="600" h="300" z="16" lat="北緯" lon="東経"]
 *
 * Yahoo! JavaScriptマップAPI
 * https://developer.yahoo.co.jp/webapi/map/openlocalplatform/v1/js/
 * Yahoo! JavaScriptマップAPIサンプル
 * https://developer.yahoo.co.jp/sample/map/sample5.html
 */

define("YAHOO_APPID", "XXXXXXXXXX");

function ymap_header() {
    echo '<script src="https://map.yahooapis.jp/js/V1/jsapi?appid=' . YAHOO_APPID . '" type="text/javascript" charset="UTF-8"></script>';
    echo '<script type="text/javascript" charset="UTF-8">';
    echo 'var ymap = [];';
    echo 'var ycenter;';
    echo '</script>';
}
add_action('wp_head', 'ymap_header');

function ymap_shortcode($attr = array())
{
    $attr = shortcode_atts(array(
        'id'  => 'map',
        'w'   => '400',
        'h'   => '300',
        'lat' => 35.6578759,  //日本経緯度原点付近
        'lon' => 139.7414501, //日本経緯度原点付近
        'z'   => '15',  //1~20
        'address' => '',
        'marker'  => '',
        'infowindow' => '',
    ), $attr);
    $html = '
    <div id="' .$attr['id'] . '" style="width:' . $attr['w'] . 'px;height:' . $attr['h'] . 'px;"></div>
    ';
    $html .= '
    <script type="text/javascript">
        ymap["' . $attr['id'] . '"] = new Y.Map("' . $attr['id'] . '");
        ycenter = new Y.LatLng(' . $attr['lat'] . ', ' . $attr['lon'] . ');
        ymap["' . $attr['id'] . '"].drawMap(ycenter, ' . $attr['z'] . ');
        ymap["' . $attr['id'] . '"].addControl(new Y.LayerSetControl());
        ymap["' . $attr['id'] . '"].addControl(new Y.SliderZoomControlVertical());
        ';

    if($attr['address'] != '') {
        //住所検索あり
        $html .= '
        var address = \'' . $attr['address'] . '\';
        var geocoder = new Y.GeoCoder();
        geocoder.execute( { query : address } , function( result ) {
            if ( result.features.length > 0 ) {
                ymap["' . $attr['id'] . '"].drawMap(result.features[0].latlng );
                ';
        if ($attr['marker'] !='') {
            $html .= '
                ymap["' . $attr['id'] . '"].addFeature(new Y.Marker(result.features[0].latlng));
                ';
        }
        if($attr['infowindow'] != '') {
            $html .= '
                ymap["' . $attr['id'] . '"].openInfoWindow(result.features[0].latlng, "' . $attr['infowindow'] . '");
                ';
        }
        $html .= '
            } else {
                $("#' . $attr['id'] . '").after("<p style=\"color:red;font-weight:bold\">住所「' . $attr['address'] . '」が見つかりません。<a href=\"https://map.yahoo.co.jp/\" target=\"_blank\">Yahoo!地図</a>で検索可能な住所を設定してください。住所が見つからない場合は、経緯度で指定します(lat:緯度 北緯○度、lon:経度 東経○度)。</p>");
            }
        });
        ';
    } else {
        //住所検索なし
        if ($attr['marker'] !='') {
            $html .= '
        ymap["' . $attr['id'] . '"].addFeature(new Y.Marker(ycenter));
        ';
        }
        if ($attr['infowindow'] != '') {
            $html .= '
        ymap["' . $attr['id'] . '"].openInfoWindow(ycenter, "' . $attr['infowindow'] . '");
        ';
        }
    }
     $html .= '</script>';
     return $html;
}
add_shortcode('map', 'ymap_shortcode');

micro:bitでサーモグラフィーを作ってみた。

久しぶりにニコニコ技術部として動画をアップロードしてみた。

覚えているうちに工作の内容をまとめておく。

makecode.microbit.org

ハードウェア

www.switch-science.com

www.switch-science.com

www.switch-science.com

  • 動画で使ったものは数年前に購入したNeoPixel互換の別物

また、たまたま手元にあったGROVE関連のパーツで配線を省略化した。
www.switch-science.com
www.switch-science.com
www.switch-science.com

AMG8833はGROVEのプロとシールドにハンダ付けして利用したが、これならGROVEシールドと直結できる。
www.switch-science.com

ソフトウェア

「最初だけ」

スイッチサイエンスのArduino用ライブラリに習い、AMG8833の「移動平均出力モード」を有効にしたが、LED表示にはさほど影響がないと感じた。

他は、NeoPixel・変数の初期化など。

「ずっと」

I2Cで数値128(0x80)を書き出し、ループで連続してI2Cの数値読み取りを行う。
各画素からは12bitの2バイトデータ(先頭1bitが符号の2の補数形式)を読む取る必要がある。
1バイトずつ読む場合は、下位8bit、上位4bitのリトルエンディアンになるので、とりあえず符号なしの2バイト整数としてUInt16LEで読み取り、剰余計算で12bitを越える部分を無視する。
読み取った値は、「0~4095」の値になるが、先頭1bitは符号なので、「2048」以上の値はマイナスの値として処理し、0.25倍した数値が温度となる。
micro:bit本体のLEDで表示するための温度の最大・最小値も都度チェックする。

センサー計測値 :
2進数     : 符号なし10進数 : 符号あり10進数 : 温度
0111 1111 1111 : 2047 : 2047 : 511.75
0011 1111 1111 : 1023 : 1023 : 255.75
0001 1111 1111 : 511 : 511 : 127.75
0000 1111 1111 : 255 : 255 : 63.75
0000 0111 1111 : 127 : 127 : 31.75
0000 0011 1111 : 63 : 63 : 15.75
0000 0001 1111 : 31 : 31 : 7.75
0000 0000 1111 : 15 : 15 : 3.75
0000 0000 0111 : 7 : 7 : 1.75
0000 0000 0011 : 3 : 3 : 0.75
0000 0000 0001 : 1 : 1 : 0.25
0000 0000 0000 : 0 : 0 : 0
1111 1111 1111 : 4095 : -1 : -0.25
1111 1111 1110 : 4094 : -2 : -0.5
1111 1111 1100 : 4092 : -4 : -1
1111 1111 1000 : 4088 : -8 : -2
1111 1111 0000 : 4080 : -16 : -4
1111 1110 0000 : 4064 : -32 : -8
1111 1100 0000 : 4032 : -64 : -16
1111 1000 0000 : 3968 : -128 : -32
1111 0000 0000 : 3840 : -256 : -64
1110 0000 0000 : 3584 : -512 : -128
1100 0000 0000 : 3072 : -1024 : -256
1000 0000 0000 : 2048 : -2048 : -512


読み取った温度を色に変換するために、micro:bitのNeoPixelで利用可能なHSL色空間を利用する。
HSL色空間では、色味を0~360度の範囲の角度で表すことができ、0度は赤となる。
室内でデモする場合を想定し、30℃以上は赤、20℃以下は青となるよう、micro:bitの計算にある「数値のマップ」と「範囲の制限」を組み合わせて利用して温度を色相に変換する。

0 赤
30 橙
60 黄
90 黄緑
120 緑
150 水色
180 水色
210 水色
240 青
270 青紫
300 紫
330 赤紫


2重ループで各画素を順番に読み、温度を計算するが、画素の並び順とLEDの接続順が異なるので、そこは計算で工夫する。
センサを裏向きに付けた場合のミラー表示(左右反転)も同時に処理する。

(センサ) 行ごとに順番は同じ。センサに向かって見たときにこの順番
7 6 5 4 3 2 1 0
13 12 11 10 9 8

(LED) 配線を短くするよう接続したために、行ごとに順番は折り返す。
0 1 2 3 4 5 6 7
13 12 11 10 9 8

「ボタンAが押されたとき」

ミラー表示(左右反転)用の設定値を入れ替え。
また、micro:bit本体のLED表示を更新。

「ボタンB」

変数に保存した、計測温度の最大値、最小値をmicro:bit本体のLEDで表示。
本体LEDの表示は遅いので、押されたタイミングで表示するテキストを作成する。




(以上)