画像データをNCプログラムに変換する

前回

katosunmemo.hatenablog.com


NCフライスで楽しく遊ぶために、画像データ(jpeg,gmp,png)をNCプログラムに変換する手順をまとめます。


つぎの工程で変換を行う。

①画像データを.dxfファイルに変換。

f:id:katosunmemo:20161230163329j:plain
ようこそ Maniacのページへ、


②レイヤ情報を持ったCADデータ作成。

f:id:katosunmemo:20161230162539j:plain
Jw_cadのページ


③CADデータをNCプログラムに変換。

f:id:katosunmemo:20161230162656j:plain
NCVC のページ - NC Viewer and Converter





では、それぞれについて詳しく説明します。

今回はこの画像を使用する。
f:id:katosunmemo:20161230163218j:plain

①画像データを.dxfファイルに変換。

使用したい画像を読み込んで、したのバーをいじったり、輪郭切抜・線図地図を切り替えてみたりしていい感じに調整する。
カラー画像でもいけます。
デフォルトで出力データはIGESにチェックが入っているため、DXFに変更してカットデータ出力。
出力スケールを聞かれるため、ワークスペースや作りたいサイズに合わせて入力し、「コンポジットカーブ」にチェックを入れて出力。


②レイヤ情報を持ったCADデータ作成。

設定→レイヤから0グループのレイヤ0を「ORIGIN」に、レイヤ1を「CAM」に名称変更。
f:id:katosunmemo:20161230164606j:plain
CAMレイヤを編集状態にして、ファイル→DXFファイルを開くから①で出力したDXFファイルを読み出す。
f:id:katosunmemo:20161230164733j:plain
ここまでやると、先程のレイヤ情報がなぜか失われているので、もう一度同じ設定をする。
原点を特に指定したい場合はORIGINレイヤを選択して円を書いておきます。
この円の中心が原点となります(画像では原点設定はしていません)
未設定の場合でもNCVCで中央や左下など設定できます。
最後にファイル→JWCファイルで保存(JWWでもいけます)


③CADデータをNCプログラムに変換。

NCVCを起動して、オプション→CADデータの読み込み設定を次のように設定。
②で原点レイヤに原点をしていない場合はこの画面の「原点データがないとき」で設定する。
f:id:katosunmemo:20161230165142j:plain

②で作成したJWCデータを読み込む。
f:id:katosunmemo:20161230170530j:plain

オプション中にある「工作機械の設定」と「切削パラメータの設定」を行う。
初期ファイルはNCVCがインストールされているフォルダ内(デフォルトはC:\Program Files (x86)\NCVC)のInit.mmcとinit.nciです。
これらを開いて、加工機や加工条件に合わせてパラメータを入力する。
自分の場合は、加工パラメータだけはワークが発泡スチレンということで主軸回転数と切削送り速度を初期値よりも大きめに設定しています。
f:id:katosunmemo:20161230170947j:plain

ファイル→NCデータ生成→標準生成でNCプログラムを出力する。
このとき、必須ではないが「NCプログラムをコード生成後に開く」にチェックを入れておくと左側にプログラムが表示されるので確認に便利。
f:id:katosunmemo:20161230171231j:plain
この画面でF5で加工シミュレーション実行、Shift+F5で一時停止もう一度F5でステップ実行、Ctrl+F5で停止ができる。

生成されるファイルは.ncdになっておりMach3の指定形式ではないが、中身はNCプログラムなので拡張子からdを抜いて完成。

あとはこのプログラムを加工機に送って加工します。
f:id:katosunmemo:20161230171514j:plain



今回の手順を応用してこんなことも出来ます!
f:id:katosunmemo:20161230172235p:plain




一応Z軸の切り込みは-1.0mmとして設定してあってプログラムもそうなっているはずだけど、-3mmまで切り込まれてるようなので、その問題が未解決…

NCフライスかった。

NCフライス買いました!
1ドル110円くらいのときで、送料関税込みで13万に収まるくらいでした。
OMIOCNC社のX3-300-USBです。

www.omiocnc.com


今回はセットアップして自動で動かすところまでをまとめたいと思います。
本記事の内容により万一損害が生じたとしても、いかなる場合もその損害について一切の責任を負いません。
非常停止スイッチに手をかけたり、可動部に挟まれないように危険には十分注意してください。


今回構築したシステムは次のとおりです。
f:id:katosunmemo:20161230013150j:plain

①それなりのスペックを持ったPCをメインPCとします。
ここではCADで設計をし、CAMを使ってNCプログラムを作ります。
ここでつくったNCプログラムは②のNCフライス制御用PCと共有しているフォルダに入れておきます。

②中古で12,000円くらいで買ってきたクソザコ控えめな性能のPCをNCフライス制御用PCとします。
OMIOCNCが販売しているNCフライスは附属のバージョンのMach3を使用することを推奨しており、その環境がWindowsXP、7だったので今回はWin7マシンを使用しています。
こちらの操作はメインPCからリモートデスクトップ接続を使って行います。(基本的にMach3にNCプログラムを読み込ませてサイクルスタートを指令することだけを想定しているため)

③今回の主役NCフライス(X3-300)
NCフライスはパラレルポートに接続するものが多いようですが、今回のものはUSB接続で動かすことができるので非常に助かりました。




では開封
f:id:katosunmemo:20161230014825j:plain

各軸のモータと制御装置が切り離されているので、組み立てます。
リミットスイッチは使わない端子は折り曲げてあります(梱包の具合で曲がったとかではないです、ノーマルオープン接続です)
リミットスイッチは機械原点に戻すために使っているようです。
機械原点を設定してソフトリミットを活用することで可動範囲外に動こうとしてしまってぶつけてしまうようなうっかり事故を防ぐことが出来ます。
f:id:katosunmemo:20161230014938j:plain
f:id:katosunmemo:20161230015018j:plain
f:id:katosunmemo:20161230015043j:plain


各軸のモータは4本のボルトをスペーサに通して固定するのですが、このスペーサが曲者で穴の位置が合っていない・・・。
おかげでボルトが内側に寄ってしまって本機に組み付かない・・・。
無理やりつけようとすると本機側のネジ山が削れていってしまうため、ここはおとなしくスペーサ側をヤスリで削って穴を広げました(組み立ててここが一番時間かかりました…)
f:id:katosunmemo:20161230015958j:plain


で、モータ取り付けてケーブル配線して完成。
つぎに制御用PCにMach3をインストールします。
インストーラは注文後にOMIOCNCからメールで送られてきます。
f:id:katosunmemo:20161230020847j:plain



手動で動作チェックします。
↑:Y+
↓:Y-
→:X+
←:X-
PageUp:Z+
PageDown:Z-
f:id:katosunmemo:20161230020953j:plain
youtu.be


次にX3-300\2-UserManual\Test-Gcode中のSpindle-run.txtでランニングをかけてみます。
f:id:katosunmemo:20161230022019j:plain
①Load G-CodeからSpindle-run.txtを選択

②非常停止を解除
この時機械側の非常停止スイッチも解除、制御装置に電源が入っていることを確認。

③主軸先端を機械の中央に移動し、X・Y・Zに0を入力してEnterを押します。(高さ方向Zも中央に)
ここが加工開始点となり、加工はこの点を原点として行います。

④サイクルスタートをします。
ソフトリミットの警告が出る場合は、座標表示の左側にあるREF ALL HOMEをクリックして機械原点に戻してから③に戻ってやり直してください。

結果。
youtu.be




最後にテストカットをしてみます。
プログラムは先程のプログラムと同じ場所にあるX3-Helper_120X70X0.5_PJ3_3002.ncです。
このままだと主軸の回転指令がないため、頭に
M03 S10000(主軸を10000min^-1で回転)
末尾に
M05(主軸停止)
を追加してください。

附属のφ3の一枚刃エンドミルを使用します。
f:id:katosunmemo:20161230023159j:plain

ワークをセットし、電源を落とした状態でモータを回す(機械原点がずれるためおすすめしない)か、電源を入れた状態で手動テストと同じ要領で加工開始地点に刃先を持っていき(X・Y)、刃先をワークに触れされます(Z)
あとは自動テストと同様にプログラムを読み込んで実行。
youtu.be

めっちゃ周りが汚れるので気をつけてくださいw
f:id:katosunmemo:20161230024021j:plain

完成はこんな感じ。
さすがにφ3のエンドミルでは文字が潰れます。
f:id:katosunmemo:20161230024105j:plain

これでセットアップは終了です。



問題点
今回つくったシステムの問題として、制御PCをRDTでつなげているため、手動で動かしている時に通信不良が起きたらこわいなぁということが上げられます。
実際キーを離しても停止しない時があって、そのときは即座に緊急停止スイッチを押せる状態にあったため無事停止できたということがありました。(原因が制御PC側にあるかもしれないですが、未検証です)
やはり、ランニングかけるのはリモートでやるにしても、実際に使っていても手動での軸の移動など調整が出来るように制御PCにもモニタとキーボードを取り付ける必要を感じます。
横着をしすぎました。。。



次回以降、加工や画像データをNCプログラムに変換することをやって行こうと思います。

ツカサブラシレスのギアヘッドを外す

CNCのスピンドルモータに使うためツカサ電工のブラシレスモータ(TG-55N-AMD-5-KA)のギアヘッドを外してみました。

www.tsukasa-d.co.jp




f:id:katosunmemo:20160809011014j:plain
と、いうわけでコレがそのモータです!
さっそくギアヘッドを外したいのですが、ここで問題発生!

f:id:katosunmemo:20160809011112j:plainf:id:katosunmemo:20160809011117j:plain

ギアヘッドを固定しているらしきネジが見当たらない・・・

もともとギアヘッドは使わず、自作の減速器をモータに直付けするつもりだったので、ここは筋肉で黒いところをこじ開けてみます!(ドリルで穴開けて、マイナスドライバ突き刺して取り外しました)
f:id:katosunmemo:20160809011252j:plain

ギアヘッド固定ネジ発見!

f:id:katosunmemo:20160809011417j:plain
というわけでここまでバラすことが出来ました。


先述の通り、自作の減速器に直付けなので、ピニオンが邪魔です。
そこで、タミヤミニ四駆用のピニオンプーラを使って外しちゃおうと思います!
f:id:katosunmemo:20160809011526j:plain


実はこのピニオンプーラ、そのままではモータ軸が太くて入らなかったので少し削ってやりました。
f:id:katosunmemo:20160809011739j:plainf:id:katosunmemo:20160809011953j:plain


これで無事自作の減速器を取り付けることができるようになりましたとさ。



後から知ったのですが、黒い部分の取り外しは今回のような方法でなくて、叩いて外すことができるそうです。




ツカサのブラシレスモータのギアヘッドを交換することはあってもピニオンまで外しちゃう需要は無いかもしれないですが、ピニオン外す必要がある!という変わった人のお役に立てば幸いです。

RaspberryPi2からつぶやく その2

前回。katosunmemo.hatenablog.com

仕様変更

・制作するものを研究室で飼っているメダカを愛でるための「おさかなbot」に変更。

部室人いるbotのつもりで開発をしていたものの、「部室にネット回線が来ていない」という重大な欠陥が発覚したため。

Twitterライブラリをtwythonからtweepyに変更。

ストリーム取得の実装がtweepyだと楽だったため(結局ストリームを監視するのではなく時限式に変更してしまいましたが...)
参考までに↓no6.hatenablog.com

・トリガーをリプライではなく時限式に変更。

リプライを受け取る→撮影→返信をするためにTLストリームを監視するようにしていたが、研究室の回線ではなぜか数分経つとストリームの取得が出来なくなってしまったため。

以上です。
3番目の実装に関しては後ほど。



写真を撮影しツイートに添付して投稿する

今回は今後画像解析とかしたいからという建前のもと、使い慣れているopenCVを使いました。
カメラから画像を取得して、jpegで保存します。
保存した画像をtweepyを使ってつぶやく簡単なプログラムです。

#get picture and tweet
def upload_picture(message):
    api = tweepy.API(auth_handler=auth)
    capture=cv2.VideoCapture(0)
    capture.set(3,640)
    capture.set(4,480)
    if not capture:
        print "Could not open camera"

    ret, im = capture.read()
    cv2.imwrite('cap.jpg', im)

    api.update_with_media('cap.jpg', status=message)

pythonで全角文字を使用する

pythonのデフォルトの文字コードはASCIIとなっており、このままだとツイートの内容を日本語にすることができない。
そこで、文字列の直前にuを付け加えることでpythonユニコード文字だと教えて日本語でツイートの内容を記述します。
d.hourは現在の時間です。

 upload_picture(str(d.hour)+u"時のようすだよ!")

時限式でつぶやく

今回、毎時0分につぶやくためにcronを使用します。
ターミナルに「crontab -e」と入力し、実行タイミングと実行プログラムを登録します。

* */1 * * * python (.pyファイルの絶対パス)

ちなみに、

分 時 日 月 曜日 コマンド

の並びになっています。
参考
cron の設定ガイド




こうして毎時0分に写真付きでツイートが投稿されるようになりました!
f:id:katosunmemo:20151104024502j:plain


さらに自動エサやり機能も付けたいと思いますが、これは卒論が終わってから気が向いたらやると思います...

【作ってみた】ゆっくり時計【眩しくない!】

夜ふと起きてしまい、時間が気になる。
でもスマホや目覚まし時計を見るとバックライトが眩しくて目がさめてしまう・・・。


と、いうわけでそんな時に便利な

_人人人人人人人人人_
> 眩しくない時計 <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^ ̄

を作ってみました!!!!

f:id:katosunmemo:20150911235909j:plain
f:id:katosunmemo:20150911235858j:plain

仕様

・外の明るさに合わせて7セグLEDの明るさを調整する。
・しゃべる!!!!
・時計としての必要最低限な機能(時刻表示、時刻調整、電源がなくなった場合のバックアップ)
・表示する情報は時刻と月日
マイコンはATmega168Pを使用する(これ大事!!)

回路図

f:id:katosunmemo:20150912001152j:plain
7セグLEDはカソードコモンのものを使用し、シンクドライバにそれぞれのGNDをつなぎダイナミック点灯で数字を表示します。

明るさ調節機能

明るさのセンサとしてフォトトランジスタを使用しました。
照度センサ(フォトトランジスタ) NJL7502L (2個入): センサ一般 秋月電子通商 電子部品 ネット通販

CdSという選択肢もありましたが、こちらのほうが見た目がカッコイイのでw
マイコンでAD変換して、その値に合わせて
(本当なら)PWMでシンクドライバのGNDにつなげたFETをスイッチングして明るさの調整をします!!(したかった!!!!!)

f:id:katosunmemo:20150912001706j:plain
こういうやりかたって出来ないんですね、勉強になりました。
このFETで点灯を間引くとすべての7セグのその瞬間に光らせようとしていたセルが光ります。

しかたがないので、割り込みの中で間引いていくことに・・・。
とはいえ、この割り込みは7セグのダイナミック点灯のために240Hzの割り込み(ひとつの7セグ点灯周期は60Hzで4個の7セグがあるため)をしており、これを利用したため、明るさは4段階のみ、点滅周期が長すぎて目に見えてちらつきます。

youtu.be

しゃべる!!

今回、音声にはAQUEST社の音声合成LSIを使用しました(今回の部品で一番高かったw)
音声合成LSI ATP3011F1−PU(ゆっくりな女声): 半導体 秋月電子通商 電子部品 ネット通販

こちらの資料に載ってる通りにアンプとスピーカーを取り付けて完成。
アンプ↓
低電圧1.2WオーディオアンプIC HT82V739 2.2〜5.5V動作 2個入: 半導体 秋月電子通商 電子部品 ネット通販

今回はI2Cで接続したので、PD2をGNDに、PD3をVCCに接続してI2Cモードにしました。
音量は可変抵抗で調整可能です。

f:id:katosunmemo:20150912003800j:plain

youtu.be

時計機能

マイコンで時間を数えても良かったのですが、電源入れ直す度に時間設定するのは面倒だったので、RTCモジュールを使用しました。
RX−8025NB使用 I2C接続リアルタイムクロック(RTC)モジュール: 半導体 秋月電子通商 電子部品 ネット通販

バックアップ電源には1Fのコンデンサを使用。
これで電源がなくなっても一週間近く持つそうです。

こちらもI2Cで接続。

時刻調整機能もバッチリ。youtu.be

使ってみた!!

f:id:katosunmemo:20150912004716j:plain
写真ではわかりにくいですが、めっちゃ便利です!

ちゃんと安眠を妨害しない程度には暗くなってくれるか心配でしたが、杞憂でした。
時報機能もつけようかと思いましたが、夜中になりだしてもこまるので付けなくて正解でしたw

ATmega168P

このマイコンは僕が電子工作を始めて初めて触ったマイコンで、かなり思い入れがあります。
ゆえに学生最後の趣味の工作としてはピッタリかな、と思って選びました。akizukidenshi.com
最近秋月ではディスコン扱いになってしまったらしく、寂しい感じです(まぁ上位互換の328と値段あまり変わらないし、あっちはArduinoで使ってたりしてるから仕方ないね)
今回、基板上のICなども魅せるようにしたいと思っていたので、最終的に使わない部品は極力載せたくありませんでした(回路設計ミスで使ってないFETが残ってしまいましたが......)
外部に接続する手段が書き込みしかなく、デバッグの方法も限られ、開発もなかなか辛かったですが、なんとか完成までこぎつきました。
ここまで育ててくれた168に感謝です。

Kinect距離画像を8bitに変換してopenCVSで使う

Kinect(V2じゃないです)で取得した距離画像は16bit(正確にはプレイヤーインデックスを含んでいたりしますが...)なので、こんな感じになります。
f:id:katosunmemo:20150617224604j:plain

でもopenCVSで処理するためにIplimageに入れるとこうなっちゃう。
f:id:katosunmemo:20150617224454j:plain


今回は16bitの画像を8bitに落としてIplimageに格納するメモです。
(変換に次ぐ変換で、ほんとにこれでいいの?って感じはしますが...)


1.KinectからDepthImageFrame型で入力
2.short型配列にピクセルデータをコピー(この段階ではまだ16bit)
3.先ほどのピクセル配列をBitmapSource型の画像化する(ここでピクセルフォーマットを8bitにする)
4.再びbyte型配列にピクセルとして格納
5.BitmapData画像をメモリにロック
6.4のピクセルを Marshal.Copyを使ってBitmapData型画像にコピー
7.先ほどのBitmapData画像のロックを解除してBitmap画像に格納している?(ゴメンナサイ、ここについてはよくわかりません)
8.Iplimageに変換

と言った流れになっています。
最初のDepthImageFrame型の入力は保存しておいて、openCVSで処理した座標の値をオリジナルから読み出すという風にしておけば分解能が下がってしまうというのも防げるのではないかなと思います。

        //距離画像取得イベント
        void kinect_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
        {
            using (DepthImageFrame frame = e.OpenDepthImageFrame())
            {
                if (frame == null)
                {
                    return;
                }
                
                short[] depthPixel = new short[frame.PixelDataLength];
                frame.CopyPixelDataTo(depthPixel);
                

                // DepthImagePixel で取得すると、16bitの距離データ+プライヤーインデックス
                // が取得できる(480x640)
                DepthImagePixel[] depth = new DepthImagePixel[frame.PixelDataLength];

                //距離画像をピクセルにバラす(中身は距離情報)
                //原点から右にナンバリング
                //距離を表示する時にアクセスする
                frame.CopyDepthImagePixelDataTo(depth);

                //距離画像を8bitに変換してIplImageにする
                BitmapSource convertedFrame_BS = BitmapSource.Create(frame.Width, frame.Height, 96, 96,
                    PixelFormats.Gray8, null, ConvertDepthFrame(depthPixel, ((KinectSensor)sender).DepthStream),
                    frame.Width * PixelFormats.Gray8.BitsPerPixel / 8);
                int width = (int)convertedFrame_BS.Width;
                int height = (int)convertedFrame_BS.Height;
                int stride = width;
                byte[] datas = new byte[stride * height];
                convertedFrame_BS.CopyPixels(datas, stride, 0);

                Bitmap convertedData_BM = new Bitmap(
                    width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed);

                System.Drawing.Imaging.BitmapData convertedBits_BD = convertedData_BM.LockBits(
                    new System.Drawing.Rectangle(0, 0, width, height), System.Drawing.Imaging.ImageLockMode.WriteOnly,
                    System.Drawing.Imaging.PixelFormat.Format8bppIndexed);

                Marshal.Copy(datas, 0, convertedBits_BD.Scan0, datas.Length);

                convertedData_BM.UnlockBits(convertedBits_BD);

                depthImageforCV_8bit = convertedData_BM.ToIplImage();

                Cv.ShowImage("処理画像", depthImageforCV_8bit);

                
            }
        }

RaspberryPi2からつぶやく その1

せっかく部室にはるばる足を伸ばしたのに誰もいなくてがっかり、そんなことが頻発する最近...

raspbianをインストールしたRaspberryPi2から部室の状態をつぶやいてみようと思います。

(Raspbian上で動くTwitterクライアントというか、botというか、そんな感じです)

作業日記としてやったことを書いていきます。

仕様

・防犯上の都合から鍵アカウントとする
・リプライを受けたら部室の様子を撮影して画像付きのリプライで返す


アカウント側の用意

使用するTwitterアカウントの設定からモバイルを選んで携帯電話の番号を登録しておきます。


TwitterのApplication ManagementのCreateNewAppをクリックし、必要事項を入力します。apps.twitter.com

Name アプリの名前
Description 説明
Website ブログとかのURL

新しいアプリの作成ができるとAPIkeyなど、開発のために必要な情報が与えられます。

「Permissions」タブをクリックし、権限が『Read and Write(読み書き)』になっていることを確認。

以上の手続きをすると連携アプリにはこんな感じに表示されます。
f:id:katosunmemo:20150524014922j:plain



RaspberryPi2側の用意

次を実行

$ sudo apt-get update
$ sudo apt-get install python-setuptools
$ sudo easy_install pip
$ sudo pip install twython

Pythonスクリプトの作成

アカウント認証の部分はApplication Managementで取得したものを使用する。

import os
from twython import Twython

#Account Check
CONSUMER_KEY = '‘Consumer key'
CONSUMER_SECRET = 'Consumer secret'
ACCESS_KEY = 'Access token'
ACCESS_SECRET = 'Access token secret'

api = Twython(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_KEY, ACCESS_SECRET)

api.update_status(status='test')

スクリプトを実行するとつぶやきが無事送信されました!
f:id:katosunmemo:20150524015230j:plain


あとはリプライをもらってから撮影して画像貼ってツイート出来るようにしないと...