iPX社員によるブログ

iPX社員が"社の動向"から"自身の知見や趣味"、"セミナーなどのおすすめ情報"に至るまで幅広い話題を投下していくブログ。社の雰囲気を感じ取っていただけたら幸いです。

Node.js+Expressの学習メーモ

Node.js+Expressの学習

久しぶりにブログを投票することになりました。EPLUのパルハットです。
最近自分が関わった業務でJavaScriptをベースにした開発が幾つかがありました。
今回自分の勉強も重ねて、JavaScriptのサーバサイドプログラムであるNode.jsとそのフレームワークExpress.jsを使って、
前回Djangoで作ったブログと同じ機能のものを作っていきたいと思いました。

環境と設定

  1. Node.js
  2. Express.js
  3. monent: Date,Timeオブジェクトの表示フォマットを変更可能
  4. express-generator

開発環境の簡単構築のためにExpress Application Generator
ツールを使用します。

詳しい環境設定と必要なモジュールのインストールの説明は避けます。

express generatorのインストール

コマンド: npm install express-generator -g

新規のExpress ApplicationをExpress-blog名で作成

コマンド: express express-blog --view=pug

以下のフォルダ構成が作成される。

f:id:ipx-writer:20181004173521p:plain

nodemonのインストール。サーバ再起動なしで、Webブラウザの自動更新を可能にします。

コマンド: npm install --save-dev nodemon

package.jsonの中身み確認します。
"scripts": {
        "start": "node ./bin/www",
        "devstart": "nodemon ./bin/www"
    },
    "devDependencies": {
        "nodemon": "^1.18.4"
    }

なっていれば大丈夫です。

コマンド:npm run devstartでサーバを起動。これでサーバを再起動しなくって、変更内容はブラウザに反映さります。

データベースの設定 MongoDB

プロジェクトフォルダの直下にmodelsフォルダを作成した後に、

post.jsファイルを作成します。コード内容は以下の通りです。

データベーススーケマの定義をタイトル、作者、内容、作成時期等にします。

const mongoose = require('mongoose');
let Schema = mongoose.Schema;
let postSchema = new Schema({
    title: {
        type: String,
        required: true,
    },
    author: {
        type: String,
        required: true,
    },
    content: {
        type: String
    },
    publish: {
        type: Date
    },
});
// Virtual for post's URL
postSchema.virtual('url').get(() => {
    return '/post/' + this._id;
});
let POST = module.exports = mongoose.model('POST', postSchema);

Applicationファイルの作成

app.jsの中身にコードを追加します。
データベースのインプットと接続関連コードを追加。

//Setup mongoose connection
const mongoose = require('mongoose');
const mongoDB = 'mongodb://127.0.0.1/post'
mongoose.connect(mongoDB);
mongoose.Promise = global.Promise;
const db = mongoose.connection;
db.once('open', () => {
    console.log("Connecting to database " + mongoDB + " ....");
})
db.on('error', (err) => {
    console.error.bind(console, err);
});
//Routesのモジュールのインプット
let indexRouter = require('./routes/index');
let postRouter = require('./routes/posts');
let usersRouter = require('./routes/users');

let app = express();
//タイムの表示フォマット変更用
app.locals.moment = require('moment');
app.use('/', indexRouter);
app.use('/posts', postRouter);
app.use('/users', usersRouter);

routerファイルの作成

routesフォルダにposts.jsファイルを作成します。中身は以下のようにします。
今回GETとPOSTだけを使います。

const express = require('express');
const router = express.Router();
const POST = require('../models/post');
// 
/* GET Postデータリストを取得.Webページに反映 */
router.get('/', function(req, res, next) {
    POST.find({}, (err, posts) => {
        if (err) {
            console.log(err);
        } else {
            res.render('index', {
                title: 'Blog',
                posts: posts
            });
        }
    })
});
/* GET Post追加Webページに反映 */
router.get('/add/', (req, res, next) => {
    res.render('add_post');
});
/* POST Post追加サブミットWebページに反映 */
router.post('/add/', (req, res, next) => {
    let post = new POST();
    post.title = req.body.title;
    post.author = req.body.author;
    post.content = req.body.content;
    post.publish = req.body.publish;

    post.save((err) => {
        if (err) {
            console.log(err);
            return;
        } else {
            res.redirect('/');
        }
    });

});
module.exports = router;

index.jsの中身、HomeページとAboutページレンダリングをここで作成します。

const express = require('express');
const router = express.Router();
// Homeページ
router.get('/', (req, res) => {
    res.redirect('/posts/');
})
// Aboutページ
router.get('/about/', (req, res, next) => {
    res.render('about', { messge: 'About content.' })
});
module.exports = router;

Viewテンプレートの作成

Viewsフォルダに幾つかのpugテンプレートを作成します。

layout.pug [Htmlページのメイン構成を定義]

    doctype html
    html
    head
        meta(charset='utf-8')
        meta(name='viewport' content='width=device-width, initial-scale=1')
        link(href='/css/style.css', rel='stylesheet')
        block title
    body
        .main-header.box-shadows
        .header
            h1 MY BLOG
            p Welcome to the blog of parhat
        ul
            li
            a(href='/') Home
            li
            a(href='/posts/add/') Add New Post
            li
            a(href='/about/') About
        .row
        .leftcolumn
            block content
        .footer.box-shadows
        p(style="opacity:0.5") Copyright © 2018 by parhat

        script(src='/js/jquery.min.js')
        script(src='/js/blog.js')

index.pug [Homeページに表示される内容]

    extends layout
    block title
    title #{title}
    block content
    each post, i in posts
        .card.box-shadows
        h2= post.title
        p(style="opacity:0.5") Author #{post.author}, #{moment(post.publish).format('MM/DD/YYYY')}
        img(src="/img/Desert.jpg" alt="Nature" style="height:380px")
        p= post.content

add_post.pug [postを追加するフォーム]

extends layout
   block content
      h1 #{title}
        .card.box-shadows
           form(method="POST", action="/posts/add")
              .row
                 .col-25
                    label(for='fname') Title
                 .col-75
                    input#fname(type='text', name='title', placeholder='Title..')
             .row
                .col-25
                   label(for='lname') Author
                .col-75
                   input#lname(type='text', name='author', placeholder='Author..')
             .row
               .col-25
                  label(for='subject') Content
               .col-75
                  textarea#subject(name='content', placeholder='Write something..', style='height:200px')
            .row
              .col-25
                 label(for='date') Created
              .col-75
                 input#subject(type="date", name='publish')
           .row
              input(type='submit', value='Submit')

about.pug [Aboutページ]

    extends layout
        block title
            title #{title}
        block content
            .card.box-shadows
                p= messge

publicフォルダにcss,js,imgフォルダがあって、
staticファイルをここから呼ぶ出す可能。今回style.cssファイルを作成します。

結果確認

コマンドプロンプトでサーバ起動します。

コマンド: npm run devstart

f:id:ipx-writer:20181004162659p:plain

http://localhost:3000/posts/

f:id:ipx-writer:20181004162706p:plain

http://localhost:3000/posts/add/

f:id:ipx-writer:20181004162707p:plain

http://localhost:3000/about/

f:id:ipx-writer:20181004162711p:plain

コマンドプロンプトでmongoDBの中身

コマンド: mongo

f:id:ipx-writer:20181004162703p:plain

まとめ

Djangoでもブログを簡単に作ることができましたが、Expressの場合も同じく簡単でした。基本考えが同じで、MVCにしたがっています。

今回は簡単なブログを作って見ましたが、次回はブログにDeleteとユーザログイン機能も追加してみたいと思います。

舌が雑なので

お久しぶりです。食いしん坊いとうです。
けっこう間が空いてしまいました。。。(´∀`;;)

知的なブログはわたしにはとても敷居が高くてですね、困りますね。

さてさて、実はわたし、独り暮らしの家に炊飯器がありません。
というのも、独り暮らしをする際にオカンから
「炊飯器なくても米は炊けるからいらないでしょ」
と言われ
「そうなのか~」
ということで、買わなかったんですね。
深い理由はありません。
しかし、そこまで熱心に料理の手伝いをしなかった娘によく言い放ったな、オカン。


はい。まぁ、そういうことで、突然ですが、フライパンでお米を炊くぞ!

研ぐときは力を入れずに適当にちょい濁りぐらいで洗うのをやめます。
(無洗米が一番楽だ…)
あと、大事なのは自分の好みとお米の品種ですね。

今回炊くのに使ったのが「ミルキークイーン」
ミルキークイーンは粘りが強いので、固めが好きな人は30分ー40分程度水につけるとしっかり固めになるかと。
私はやわらかふくふくご飯が好きなので、長めの1時間ちょい水につけます。

これは適当に洗ってフライパンにどっぽーんしたお米。
f:id:ipx-writer:20181001184847j:plain

火は強め
f:id:ipx-writer:20181001184920j:plain

これくらい沸騰したら
f:id:ipx-writer:20181001184926j:plain

火は小さくして10分放置。
f:id:ipx-writer:20181001184934j:plain

はい炊けた
f:id:ipx-writer:20181001185237j:plain

一応わかりづらいけどちゃんと自分で食べておいしいなぁと思う程度には炊けました。
結構簡単ですよね。お米炊くのが難しいのって、昔は火加減を常に人力で扱ってたからだと思うんですよ。
現代はコンロが常にいい火加減なので、沸騰後は弱火にしてキッチンタイマー10分かけて放置です。
私はスマフォゲームしてぼんやり炊きあがりを待ちます。

このあと本来は蒸らしとかも必要なんですけど、私は速攻でラップに包んで1食分ずつ分けて冷まして冷凍庫行きです。
ラップに包んで蒸気が逃げないのでまぁまぁ蒸らし的な効果もあるんじゃないかなぁ…とか思うことにしています。

炊くときの水分量よりも、お米の特徴を見てどれだけ水に浸すかを調整したほうがいいかなぁ、と体感してます。
個人的には「青天の霹靂」がとてもちょうどいい固さでおススメです。どまんなかあっさりです。
もちもちしっかり重めが好きな人はミルキークイーンのがおススメですかね、独断と偏見で。

いつかはお米の食べ比べしたいですね。
舌が雑なので見分けられるか自信はないですけど。


少し前まで土鍋で炊いていたのですが、フライパンのほうが後片付けが簡単なうえに結局わたしの舌が雑なので味も一緒だと。
小さい土鍋だったもので1~2合までしか炊けなかったんですよね。
フライパンは3合も4合もへっちゃらなので、一気に炊けるのがいいのです!作り置きに優しい。
大きい土鍋持ってる人は土鍋でもほぼ気にせずやれると思います。

ということで、炊き込みご飯もほぼ同じ要領でできるので、みなさんぜひ挑戦してみてください。

録画用HDDを修復してみた話

EPLUのタキヤマです

もう夏も終わりですね
今年は夏らしいこと色々したので少し寂しいものがあります
冬は苦手でスノボくらいしか楽しみが無いので、来年の夏が待ち遠しいです


さて、前回はNoSQLについて書いてみたりもしましたが
技術者らしい真面目なネタはあまり持ち合わせていないので、今回は最近あった身近なことをそれっぽく書いてみます

続きを読む

NVIDIA GTC JAPAN 2018 にご来訪いただきありがとうございました

9/13, 14 に開催されました GPU Technology Conference (GTC) JAPAN 2018 におきましては、多くの方に弊社ブースへお立ち寄りいただきまして誠にありがとうございました。

弊社ブースでは、 NVIDIA 社の自立走行車開発プラットフォームである Drive PX 2 を用いて、 3D LiDAR でリアルタイムに取得した点群情報から GAN (Generative Adversarial Network) を利用して画像補完することで物体認識率を向上させるデモをご紹介させていただきました。
f:id:ipx-writer:20180925114137j:plain:w266:h398f:id:ipx-writer:20180925114123j:plain:w365:h274f:id:ipx-writer:20180925114100j:plain:w403:h302

また、テクニカルセッションでは、株式会社 SUBARU 小山様の「 SUBARU 将来の自動運転と知能化技術の取り組みについて」講演での強化学習部開発に弊社もご協力させていただきました。
講演の内容は Car Watch 様の以下記事に掲載されておりますので、こちらも是非ご覧ください。

f:id:ipx-writer:20180925114824j:plain:w380:h214

Simulinkによる順次シミュレーションを作る

今回のブログ担当のシロハです。
今回のテーマは、私が業務で使用することのあるMATLAB/Simulinkというツールについてです。

初めに

今回の記事で扱う内容は、mファイルを用いたSimulinkの順次シミュレーションの実行についてです。
また、MATLAB/Simulinkの基礎(mスクリプトの扱い方、Simulinkでのモデル作成やシミュレーションの実行方法)を知らないと理解が難しい内容が含まれます。

順次シミュレーションとは

初めに、順次シミュレーションとは、事前に複数パターンのシミュレーションの仕込みをしておいて、シミュレーションを1度実行すれば、全てのシミュレーションを終わらせてくれる、というものです。

順次シミュレーションの目的

1Dシミュレーションでは一般的に、3Dシミュレーションよりも1回のシミュレーションに時間が短いですが、その分複数パターンの検証が必要になることが多い、ということを何度か経験しました。
ただし3Dよりは早いといっても、モデルと検証条件によっては1パターンで1時間以上かかることもよくあります。
ということで今回の目標は、
順次シミュレーションを用いることで、帰宅前や金曜日の帰り際にシミュレーションを実行する⇒次の出勤時にシミュレーション結果が確認できる、というものを目指します。

順次シミュレーションの流れ

まず、順次シミュレーションを行う為にMATLAB/Simulinkにどのような作業をして欲しいのか、について考えます。

  1. 複数パターンのシミュレーションをコンピュータに順次行ってもらうために、mスクリプトからシミュレーションを実行する必要があります。また、実行したいパターン数だけシミュレーションを繰り返す必要があります。
  2. 全く同じシミュレーションを繰り返しても意味はないので、シミュレーションのたびにブロックの配置や結線・パラメータなどを書き換える必要があります。
  3. シミュレーションを実行した後で結果が残っていないのでは意味がありません。シミュレーション結果を保存して、外部にエクスポートする必要があります。

では、これらの作業をmファイルに書き込んでみましょう。

  1. matlabスクリプトSimulinkのシミュレーションを実行する場合は、sim関数を用います。
    使い方:sim('シミュレーションしたいSimulinkのモデル名')
    また、複数のパターンをシミュレーションする必要があるため、sim関数や、この後説明する要素をfor文の中に記述する必要があります。

  2. スクリプトからブロックの配置や結線・パラメータ書き換えを実行します。ブロックを配置・パラメータ変更するためにはブロックの持つパラメータ名を知っておく必要があります。
    知っておく必要のある関数について
    ブロックパラメータの変更:set_param
    ブロックパラメータの取得:get_param
    ブロックの配置:add_block
    ブロックの結線:add_line
    説明すると長くなるため、関数の詳細はヘルプを参照してください。

  3. :ブロックパラメータ名の調べ方
    その1:以下のページでブロックパラメータ名を調べることが出来ます。
    https://jp.mathworks.com/help/simulink/slref/block-specific-parameters.html

    その2:get_param関数を用いてブロックパラメータ名を調べます。
    ブロックパラメータは、関数add_blockでブロックを配置したり、set_paramでブロックパラメータを変更する際に必要になります。
    a:パラメータ名を調べたいブロックをダブルクリックして、調べたいパラメータの値を適当な値(11111111など)にします。

    b:パラメータ名を調べたいブロックをクリックします。
    (手順b~cまでの間に他のブロックをクリックしないこと。分かる方向けにいうとgcbを用いているため)

    c:次のコードをエディタ、またはコマンドウィンドウで実行します。
    DATA=get_param(gcb,’ObjectParameters’);
    PARAM=fieldnames(DATA);
    for i=1:length(PARAM)
    PARAM{i,2} = get_param(gcb,PARAM{i,1});
    end

    d:実行した結果がワークスペースのセル配列'PARAM'に保存されています。
    PARAMの1列目がパラメータ名、2列目が1列目に対応したデータとなっています。
    セル配列 PARAM の中に、先ほど設定した適当な値があるので、その隣の1列目に書いてあるのが目的のパラメータ名となります。

  4. シミュレーション結果を保存する方法はいくつかありますが、今回はSimulinkに「To Workspace」ブロックを配置してから、xlswriteでエクスポートすることでデータを保存します。
    ちなみに、単純にデータを保存するだけならばSimulinkに「To File」ブロックを置くのが一番簡単です。ただ、Simulinkとの連携に限らず、xlswriteでデータをエクスポートするという手法が便利であること、またWorkSpaceに一度データを残すことで、WorkSpace上のデータを処理してからエクスポートすることが可能になるなど応用が利くため、今回はxlswriteを用います。

基本的な骨組み

先ほどの1~3を組み合わせて、順次シミュレーションの骨組みを作ると以下のようになります。

S = シミュレーションのパターン数;
for i=1:S %S回シミュレーションを実行する
  switch i %case文の中にパラメータやソルバなどの、シミュレーション毎に変更する点を記述する
    case 1
      set_param(~)
      add_block(~)
      add_line(~)
    case 2
      set_param(~)
      add_block(~)
      add_line(~)
    case 3
    ・・・
    otherwise
  end
sim(‘モデル名’) %シミュレーションを実行
xlswrite(~)   %データをエクスポートする
end

この骨組みを基本として、Switch文の中に必要に応じて関数を追加すれば順次シミュレーションの完成です。

まとめ

MATLABは検索すると大体のことは知ることが出来るため、あえて今回は初心者向けではない内容にしております。MATLABの基本について知りたい方は「MATLAB 使い方」で検索すると良いと思います。

また、今回はあえてMATAB/Simulinkを連携させる形で順次シミュレーションを行っていますが、一般的にシミュレーションに掛かる時間を減らす場合は、シミュレーションの高速化や動的システムの並列シミュレーションを用いるようです。
尤も私がよく知らないために書けないのですが。

隠れマルコフモデルのお勉強

ご無沙汰しております。マルコフ部(非公認)部長の小川です。

業務上で隠れマルコフモデル(HMM)について理解する必要がでており、実装に際して理論の方のお勉強をしようと思います。

今回は第一回という事で条件付き確率についてお勉強した内容を記そうと思います。

続きを読む

NVIDIA GTC JAPAN 2018 のご案内

来週 9/13, 14 に NVIDIA 社主催の GPU Technology Conference (GTC) JAPAN 2018 が開催されます。
今年は弊社も SILVER SPONSOR として協賛させていただいております。

当日はスポンサーブースにて弊社の深層学習活動の一環として、 3D LiDAR でリアルタイムに取得した点群情報から GAN (Generative Adversarial Network) を利用して画像補完することで物体認識率を向上させるデモをご紹介させていただく予定です。

イベント参加の折には、是非弊社ブースへお立ち寄りください。