Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

monodevelopでpostgresqlアクセス

今回は、monodevelopにて直接sqlに接続する方法についてまとめます。
postgresqlmysqlであればサーバ不要で、直接sqlに接続することができます。
sqliteだと出来ないようです。

まぁ、sqlitepostgresqlmysqlは用途が異なるのでそんなものか、と思いますが。

今回はpostgresqlを利用して、monodevelopと直接接続したいと思います。

なお、こちらの記事によりmonodevelopがインストールされていることを前提にします。
elsammit-beginnerblg.hatenablog.com

postgresqlセットアップ

まずは下記でpostgresqlをインストールします。

apt-get install -y postgresql

次にpostgresqlを外部アクセスできるように設定します。

sudo vim /etc/postgresql/10/main/postgresql.conf

によりコンフィグファイルを編集します。
編集箇所ですが、60行目付近のlisten_addressesに対して、

#listen_addresses = 'localhost' 
listen_addresses = '*' 

次に、

vi /etc/postgresql/10/main/pg_hba.conf

に対して100行目あたりを下記の通り編集します。

host    all             all             192.168.56.101/32            md5 ← IPアドレスは必要に応じて変更.

そして再起動を実行。

/etc/init.d/postgresql restart

これでpostgresqlのセットアップは完了です。

次にデフォルトユーザ名であるpostgresのパスワードを変更します。
ユーザをpostgresに切り替えて、

psql

を実行!!
その後、

alter role postgres with password 'pwd123'; ←pwd123にはパスワードを入力.

を実行。

そして、外部アクセスできるか下記で確認。

psql -U ユーザ名 -d データベース名 -h ホスト名

ログインができればセットアップは問題なく行えています。


monodevelopでのsqlアクセス

まず、monodevelop上でパッケージをインストールします。
こちらのパッケージを押下するとパッケージ追加画面が表示されるので、
f:id:Elsammit:20200911222934j:plain

検索窓で"Npgsql"を入力。
一番トップにNpgsqlが表示されるかと思うので、パッケージを追加を押下。
f:id:Elsammit:20200911223050j:plain

次にこちらを参考にボタンとクリックイベントをセットして、、、
elsammit-beginnerblg.hatenablog.com

クリックイベント内で下記の通り実装します。

void Button_Clicked(object sender, EventArgs e)
{
   string conn_str = "Server=192.168.56.101;Port=5432;User ID=postgres;Database=testdb;Password=postgres";
    using(NpgsqlConnection conn = new NpgsqlConnection(conn_str))
    {
        try
        {
            conn.Open();

            string cmd_str = "insert into testTbl values('1','AAA')";
            var cmd = new NpgsqlCommand(cmd_str, conn);
            cmd.ExecuteNonQuery();

            conn.Close();
        }
        catch
        {
            Console.WriteLine("error");
        }
    }
}

ServerにはIPアドレス、Portにはポート番号(postgresqlのデフォルトは5432)、IDはユーザ名、Databaseにはデータベース名、
PasswordにはIDで設定したユーザ名のパスワードを入力します。


。。。C#でのpostgresqlにアクセスするコードと同じですねw

■最後に

sqliteですとサーバ上にsqlを起動した状態にはできないですが、その分サイズが小さく軽いのが利点となります。
用いるsqlによってはアプリから直接sql文でDBにアクセスできるため、使い分けるとよさそうですね。

React マウスホイールで画像拡大・縮小

今回はReactにてマウスホイールを動かすと画像拡大・縮小すようにしてみたいと思います。
完成イメージはこんな感じ。
f:id:Elsammit:20200909231642g:plain


機能としては、
 ・画像上でマウスホイールにより拡大・縮小が行える
 ・画像上でマウスを動かすと画像が領域内で動く
です。

■マウスホイールでの拡大・縮小

マウスホイールを動かした際のイベントとして"OnWheel"があります。
こちらのイベントにマウスホイールを動かしたら画像の拡大・縮小を行えるようにすればOKです。

ソースはこちら。

zoom = (e) =>{
    const {zoom} = this.state;

    var buf;
    if(e.deltaY > 0){
        buf = zoom - 0.1;
    }else{
        buf = zoom + 0.1;
    }
   this.setState(()=>{
        return {
            zoom:buf
        }
    })

    document.getElementById("img01").style.zoom = buf;
}

render() {
    return(<div>
    	<div id="imgID" onWheel = {(e) => this.zoom(e)}  className="mouseImg">
        	<img src={Imagefile} id="img01" heigt="100px" width="100px"  />
       </div>
    <div>)
}

イベント発生時に渡されるe内のdeltaYにてマウススクロール時の移動量が格納されております。
deltaYは手前方向に回すとプラス、奥方向に回すとマイナスになります。

今回は手前方向に回した場合に縮小してほしいため、deltaYがプラスであればzoomをマイナスにしています。
そして、imgタグのidを指定してzoom値をセットしています。

■マウス移動に伴う画像の移動

所定領域に収める形で画像の拡大を行うと画像が見切れてしまいます。
そこで、マウスを動かした際に画像が動くようにしました。

マウスを動かした際のイベントは、”onMouseMove”なのでこちらを用います。

ソースコードはこちら。

onMouseMove = (e) =>{
    var element = document.getElementById("imgID");
    element.scrollTop = element.scrollTop - e.movementY*10;
    element.scrollLeft = element.scrollLeft - e.movementX*10;
}
render() {
    return(<div>
    	div id="imgID" onWheel = {(e) => this.zoom(e)} onMouseMove = {(e) => this.onMouseMove(e)} className="mouseImg">
        	<img src={Imagefile} id="img01" heigt="100px" width="100px"  />
       </div>
    <div>)
}

イベント発生時に渡されるe内には現在のスクロールの位置を示すscrollTop 、scrollLeft や
マウスの移動量を示すmovementY、movementXがあります。

これらを用いて、マウスを動かした方向に応じてスクロールの位置(scrollTop 、scrollLeft)を変化させればOKです。

■最後に

マウスホイールによる画像の拡大・縮小とマウス移動時の画像位置移動ですが、
よさげなサイトが見当たらず、苦戦しました。。。
まぁ、動いたからよしとします!!

ただ、スライドバーが表示されているのは気に入らないので後で削除を試みたいと思います!!





raspberry Pi で音声認識(julius使って見た)

今回も引き続きラズパイを使っていきます。
音声認識をラズパイでやってみようかな?と思い、音声認識ソフト?のjuliusを使って見たのでセットアップ手順等をまとめたいと思います!!

■juliusとは?

音声認識システムの開発・研究のためのオープンソースの高性能な汎用大語彙連続音声認識エンジンのことです。
数万語彙の連続音声認識を一般のPCやスマートフォン上でほぼ実時間で実行できる軽量さとコンパクトさを持っているようです。

Julius はオープンソースソフトウェアであり、プログラムはC言語で書かれており、さまざまなプラットフォームへの移植や改造が容易。
ライセンスはオープンライセンスで,商用利用への制限もないようです。
GitHub - julius-speech/julius: Open-Source Large Vocabulary Continuous Speech Recognition Engine


■julius環境構築

まずラズパイで音声を収集しなければならないためマイクが必要です。
今回は、こちらのUSBマイクを利用しました。

【クーポン有】 SANWA USBマイクロホン コンデンサー 単一指向性 タッチ式ミュートボタン付き # MM-MCU02BK サンワサプライ (Apple製品関連アクセサリ)

価格:3,220円
(2020/9/7 20:30時点)
感想(0件)

結構集音性能が高くて重宝しています!!

USBオーディオをメインで使用するためにラズパイ側で、

/etc/modprobe.d/alsa-base.conf

を下記の通り編集。

options snd slots=snd_usb_audio,snd_bcm2835
options snd_usb_audio index=0
options snd_bcm2835 index=1

そして、

~/.profile

に下記を追記。

export ALSADEV="plughw:0,0"

最後にこちらを実行。

sudo julius -C testmic.jconf -charconv SJIS UTF-8
sudo modprobe snd-pcm-oss
sudo sh -c "echo snd-pcm-oss >> /etc/modules"
export AUDIODEV=/dev/dsp1
sudo apt-get install alsa-utils sox libsox-fmt-all


次は、実際にjuliusをダウンロードしていきたいと思います。
juliusをgithubから取得し、解凍。

wget https://github.com/julius-speech/julius/archive/v4.4.2.tar.gz
tar zxvf v4.4.2.tar.gz julius-4.4.2/

今回はv4.4.2を利用していますが、少し古いかもしれません。
最新バージョンを確認の上、ダウンロードしてみてください。

次にビルドとインストールを実行。

cd julius-4.4.2/
./configure
make
sudo make install

こちらのコマンドを実行してバージョン情報が表示されればインストールはOKです。

julius -version


簡単簡単!!と思ったのもつかの間、juliusだけをインストールしただけでは動かないようです。。。
juliusと合わせて、
・音響モデル(音素HMM)
・単語辞書
言語モデル(単語N-gram
が必要なようです。

幸いにも上記はディクテーションキットとしてパッケージで用意されているため、
ありがたくこちらを利用。

wget --trust-server-names 'http://osdn.jp/frs/redir.php?m=iij&f=%2Fjulius%2F60416%2Fdictation-kit-v4.3.1-linux.tgz'
wget https://github.com/julius-speech/grammar-kit/archive/v4.3.1.zip
tar zxvf dictation-kit-v4.3.1-linux.tgz
unzip v4.3.1.zip

これで準備完成です。


■juliusによる音声認識

では実際にjuliusにて音声認識を実施してみます!!
2種類方法があります。
まず1つ目は、

cd dictation-kit-v4.3.1-linux
sudo julius -C main.jconf -C am-gmm.jconf -demo

2つ目は、

cd grammar-kit-4.3.1/
sudo julius -C testmic.jconf -charconv SJIS UTF-8

どちらも、こちらのようなメッセージが表示されればOKになります!!

<<< please speak >>>

1つ目の方がの日常の言語が登録されているのでサンプルとして使うのにはよいかもしれません。



■最後に

こういうインプットデバイスからデータ蓄積していって機械学習とか出来れば面白そうだな、と思っている今日この頃。
だけど、機械学習は勉強しているけど実際に作れたりしないので、まずは何か作ってみようかな?


ラズパイで測距センサ(VL53L0X)の利用

今回はラズパイで測距センサを利用してみたいと思います!!
別な理由で購入していたセンサでしたが、試しにラズパイで使えるかな?と思い試しに使って見た次第ですw


■使用環境

用いたデバイスは下記です。
・ラズパイ4
・測距センサ


測距センサですが、こちらを利用。

ToFレンジファインダセンサブレークアウトボード、電圧レギュレータ付 - VL53L0X

価格:1,323円
(2020/9/6 16:37時点)
感想(0件)


VL53L0Xを用いた構成は下記となります。
f:id:Elsammit:20200906172530p:plain

今回はpythonで実装していきたいと思います。


■ラズパイ設定

VL53L0XはI2Cで通信するため、ラズパイにてI2Cを有効にする必要があります。
まず、ラズパイにてこちらを実行します。

sudo raspi-config


下記画面が表示されるため、
f:id:Elsammit:20200906165235p:plain

5 Interfacing Options Configure connections to peripherals ⇒ P5 I2C Enable/Disable automatic loading of I2C kernel module
の順番で選択し、"はい"(有効)を選択する。

さらにこちらをインストールしておきます。

sudo apt-get install python-dev and python3-dev
sudo apt-get -y install python-smbus i2c-tools

最後に下記を実行してVL53L0Xとラズパイのい疎通確認を行います。
下記を実行!!

sudo i2cdetect -y 1

下記のようにチャネル番号(今回は0x29)が表示されていればOKです。
f:id:Elsammit:20200906165752p:plain


■測距センサ利用

実はVL53L0X、サンプルソースが公開されておりますw。
こちらを実行しサンプルソースをダウンロード。

git clone https://github.com/johnbryanmoore/VL53L0X_rasp_python.git

VL53L0X_rasp_pythonというフォルダが生成されているかと思いますので、

cd VL53L0X_rasp_python/
make

を実行。

python配下にサンプルソース(VL53L0X_example.py)が格納されているため、

cd python
sudo python3 VL53L0X_example.py

を実行。

こちらのようにログが流れればOKです!!
f:id:Elsammit:20200906171204g:plain


VL53L0X_example.pyのソースコードですが、こちらのようになっており、0.5秒ごとに距離測定結果をログに出力します。
rangeが1~101なので100回分測定したら自動的に終了になります。

for count in range(1,101):
    distance = tof.get_distance()
    if (distance > 0):
        print ("%d mm, %d cm, %d" % (distance, (distance/10), count))

    time.sleep(timing/1000000.00)
    time.sleep(0.5)

tof.stop_ranging()

基本的にやりたいことに合わせてこちらのコードを改変していけばよさげですね。




■最後に

測距センサを用いたおもちゃでも作ってみようかな?
クラウドにセンサ値とかを上げたら面白いこと出来るかな??
ちょっと考えてみたいと思いますw。



Go言語でのCORSエラーに対する対応

お久しぶりです!!
8月末から忙しくなってしまい、ブログの更新が出来ていませんでした。。。
やっと落ち着いたので、再開していきたいと思います!!


今回はGO言語をサーバーサイドで動作させた際に発生したCORSエラーの対応についてです。

■CORSって?

CORSとはCross Origin Resourse Sharingの略であり、javascritのAjax通信を行う際に、安全に情報送受するための規約とのことです。
基本的にAjaxは同一オリジン(Origin)同士での通信を前提としているのですが、CORSにより異なるオリジン間での通信の安全性が保障されているようです。


f:id:Elsammit:20200905135844p:plain



ここで、オリジンって何ぞや?ですが、
ドメイン(domain)と比較するとイメージがわきやすいです。

ドメインとオリジンそれぞれ具体例はこちら。
ドメイン(domain):yahoo.co.jp
・オリジン(origin):https://yahoo.co.jp:443

要するに、オリジンは

オリジン = protocol + ドメイン + port番号

詳しいことはこちらに記載されておりました。
なんとなく CORS がわかる...はもう終わりにする。 - Qiita
【CORS】クロスドメインによるエラーについて - Qiita
オリジン間リソース共有 (CORS) - HTTP | MDN


■遭遇したエラー

今回私がGO言語で遭遇したエラーはこちらになります。

~~ has been blocked by CORS 
policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

どうやらCORSによってアクセスがブロックされているようだが、、、
う~~んわからん。。。


■解決方法

調べていったところ、どうやらCORS対策を行わなければならない模様。

まず、こちらを実行しcorsをダウンロード+インストール。

go get github.com/gin-contrib/cors


そして、go言語でのコードはこちらのようにすればよいです。

import "github.com/gin-contrib/cors"

func Do_Get(){
	r := gin.Default()
	config := cors.DefaultConfig()
     config.AllowOrigins = []string{"有効にするオリジン"}
     r.Use(cors.New(config))
	r.POST("/Get", func(c *gin.Context) {
		~~
	})
	r.Run() // listen and serve on 0.0.0.0:8080
}

func main() {
	Do_Get()
}

先ほどインストールしたcorsをimportし、

import "github.com/gin-contrib/cors"

コンフィグとして有効にするオリジンを登録すればよいです。

config := cors.DefaultConfig()
config.AllowOrigins = []string{"有効にするオリジン"}
r.Use(cors.New(config))

■最後に

認証系はやはり難しいですね(-_-;)
ハマると結構厄介です。。。

ただググれば何とか解決策が見つけられるにはかなりの救い!!
これからも頑張って色々手を動かしていきたいと思います!!

Go言語でのPost/Getとデータベース連携

今回は前回から導入したGo言語+GinでPost/Getをリクエストを受けとり、受け取ったデータをデータベースに書き込む処理について書いていきたいと思います!!
使用するデータベースはsqlite3にしました(特に理由はないですが、強いて言うなら慣れているためですw)。
f:id:Elsammit:20200824010216p:plain


Go言語やGinの導入については、こちらをご参照ください。
elsammit-beginnerblg.hatenablog.com



■Get方法
Getは前回のソースにも登場していますが、Getリクエストにて渡されたデータを受け取るところは未記載でした。
リクエストにて渡されるデータを取得する場合にはこちらのように実装すればよいです。

func Do_Get(){
	r := gin.Default()
	r.GET("/Get", func(c *gin.Context) {

		ret := c.Query("hoge")
		fmt.Println("hoge:",ret)


		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run() 
}

こちらは、
http://アドレス:8080/Get?hoge="データ値"
のように指定してGetリクエストを行われた場合、hogeに与えられたデータ値をret変数に格納する実装になっております。

■Post方法
次にPostです。
Postにてこちらのようなjsonデータを受け取ることを想定します。

{
    "Id":"1",
    "Name":"namae"
}


上記jsonデータを受け取る実装はこちらになります。

type Test struct {
	Id	string
	Name string
}

func Do_Post(){
	r := gin.Default()

	r.POST("/ping/", func(c *gin.Context) {

		var js Test
		c.BindJSON(&js)

		c.JSON(200, gin.H{
			"message": "pong",
		})
	})
	r.Run()
}

jsonデータと同じ構成の構造体をあらかじめ用意しておき、こちらの構造体にjsonデータを直接格納すればよいです。


■Sqlite3への書き込み
前提として、下記データベースが用意されているものとします。

DB名:db.sql
テーブル名:NameTbl
カラム名:id, Name

まずこちらを実行し、go言語でsqlite3を使えるようにします。

go get github.com/mattn/go-sqlite3 


そして、sqlite3へのデータ書き込みはこちらになります。
DB_Write関数の引数として与えられたId, Nameをデータベースに書き込んでいます。

import (
	"database/sql"
	"fmt"
	"log"
	"github.com/gin-gonic/gin"
    _  "github.com/mattn/go-sqlite3"
)

func DB_Write(Id string, Name string){
	
	DbConnection, err1 := sql.Open("sqlite3", "./db.sql")

	if err1 != nil {
		log.Fatal(err1)
	}

	cmd := "INSERT INTO NameTbl (id, name) VALUES (?, ?)"
	_, err := DbConnection.Exec(cmd, Id, Name)

	if err != nil {
		log.Fatalln(err)
	}
}

 ・sql.Openでdb,sqlへのコネクション実行
 ・コネクションしたdb.sqlに対して、cmdで定義したコマンドを.Exec関数で実行
といった処理の流れになります。
また、コマンドに変数を与える場合には、"?"を利用しExec関数の引数として与えればよいようです。


■最後に
Go言語はまだまだ勉強中です。
写経レベルしか出来ていないので、使いながら慣れていきたいと思います。

■参考
Golang+Ginについての備忘録(ちょこっとGorm) - Qiita
(メモ)mattn/go-sqlite3を使ってみた - Qiita

javascriptで花火打ち上げ

暑いですね。夏ですね。
だけど今年はコロナウィルスの影響で軒並み花火大会がなくなってしまいなんだかさみしい夏になりました。。。
ここ数年は毎年近所の花火大会行っていたのですが、今年はなし。。。
f:id:Elsammit:20200829182639p:plain

このまま夏が終わってしまうのはなんだか悲しい!!泣
悲しいです!!泣


悲しいので花火を自作することにしました!!ww
もちろん本物は作れないので、プログラムですww。


どうやって作ろうかな??と思いながら調べてみたところ、javascriptで作ることができるとのこと!!
qiita.com


どうやら、p5.jsを用いるといいとのこと。
p5.jsは、
processingをjavascriptに移植したもの
とのことです。
p5js.jp
qiita.com



qiitaに上がっていたソースコードをそのまま流用しつつ、javascriptを別ファイルに移植してみました。
ソースコードの内容としては、p5.jsライブラリに渡すためのパラメータをセットしつつ必要なAPIをコールしている感じでした。

動かした結果、こちらのようになりました。
f:id:Elsammit:20200829182705g:plain


だけど、ただソースコピペするだけでは味気ないな。と思い、音声を付けることにしました!!
音声出力のコードはこちらになります。

audio.oncanplaythrough = (event) => {
    var playedPromise = audio.play();
    if (playedPromise) {
        playedPromise.catch((e) => {
            console.log(e)
            if (e.name === 'NotAllowedError' || e.name === 'NotSupportedError') { 
                console.log(e.name);
            }
        }).then(() => {
            console.log("playing sound !!!");
        });
    }
}

全体のソースはこちらに格納しました。
https://github.com/Elsammit/Fireworks.

音声あり:SoundOn ブランチ
音声なし:SoundOff ブランチ



こちらURLで花火が見れます。
夏を感じられるかな?と思いますので、ぜひ!!
※こちらは音がならないバージョンになります。
https://elsammit.github.io/Fireworks/



最後に、、、
これで少しは夏を感じられた気がします。そう思いたいだけかもww。
とりあえず自己満足w。