豆腐とコンソメ

豆腐とコンソメ

ラズパイ工作ともろもろのプログラム勉強記録

MENU

CSSの勉強の成果物をHerokuで管理する

仕事帰りの奥さんを喫茶店で待っていた。

表参道の喫茶店である。

Mac Book Proを持ち込み、カタカタカッターン!とカッコよく作業をしていた。

ターミナルの黒色背景に緑文字は、僕ってかっこいい!という自己陶酔に浸るにはぴったりの環境だ。

$ mkdir hoge 
$ touch hoge.txt

やっぱり、hoge〜はいらないやと

$ rm -r *

と、やった直後に気がついた。

作業ディレクトリを変更していた。

結果、意図するものと異なるものを消してしまい、ここ1週間あまり作業していたソースやらなんやらが消失してしまった。

ファイルはローカルにしか存在しておらず、githubにもあげていなかった。

雑といわれがちな自分だけれども、表参道・喫茶店・MacBookPro + Terminalという組み合わせが、いつも以上の悲劇を呼んでしまった。

このことから、今更ではあるのだけれども、成果物をリモート上で管理していく習慣をつけていこうと思う。
(そもそもrm -r * なんてやらないほうがいいのだけれども)

そこで今回は、試しにHerokuを用いて作業物を管理してみたいと思うので、それをするにあたっての作業記録を書いていく。

ちなみに消えてしまったものは、以下の「Node.jsを始めてみよう」を参考にいろいろ試していたものだった。

わかりやすくて、すごい読みやすい内容なので自分みたいにNode.jsを始めたばかりの方にはおすすめしたい。 僕は、こういうものを書けるようになりたい。

今回のHerokuを使う、というのものこれをきっかけに使ってみることにした。

github.com

作成したサイト

以下のように、HerokuにWebサイトをデプロイして、CSS練習用のページをつくってみた。

CSS練習用のTOPページ

あれ、Githubでソース管理して、ローカルで確認すればいいんじゃないの?っていう心の声は押さえましょう。

Herokuを使いたいんだよね!そうだよね!

まだ触ったばかりですが、githubにあげたタイミングでHerokuにもあげていこうかと思います。
(そもそもgithubにあげてなかったのが問題ですが)

Herokuをつかってみる

今回、sample_basic_cssというディレクトリ配下に、以下のnode.jsのプロジェクトを作成したので、こちらをHerokuにデプロイしていきます。

sample_baisc_css配下

.
├── app.js
├── bin
├── node_modules
├── package-lock.json
├── package.json
├── public
├── routes
└── views


アカウント作成

Herokuにアクセスして、新規にアカウントを作成します。
今回のように、データベースとかまったくつかわないシンプルなサイトであれば、クレジットカードとかの情報も不要でした。

www.heroku.com


Heroku CLIをインストールする

Herokuのサイト上からも、アプリケーションの作成やらなんやらできるみたいですが、CLIツールもあるので、こちらをインストールします。

MacOSであればHomebrewでつっこんじゃいましょう。

$ brew install heroku

Windowsであれば、インストーラーがあるみたいです。
devcenter.heroku.com


デプロイの準備

HerokuへのデプロイはGitを使って行います。
sample_baisc_cssはGithubで管理していたので、さくっといけました。

Procfileの作成

Herokuにデプロイする際に必要なファイルとのこと。
エントリーポイントがわかるように必要なのかな。

Procfile

web: node ./bin/www

sample_baisc_css配下

.
├── Procfile  //追加
├── app.js
├── bin
├── node_modules
├── package-lock.json
├── package.json
├── public
├── routes
└── views
Herokuでアプリケーション作成

「heroku create <アプリケーション名>」で空のアプリケーションを作成します。
作成されると、アプリケーションのURLとgitのリポジトリのURLが表示されます。

$ heroku create sample-basic-css
Creating ⬢ sample-basic-css... done
https://sample-basic-css.herokuapp.com/ | https://git.heroku.com/sample-basic-css.git

リモートのリポジトリもherokuという名前で作成されていますね。

$ git remote -v
heroku  https://git.heroku.com/sample-basic-css.git (fetch)
heroku  https://git.heroku.com/sample-basic-css.git (push)
origin  https://github.com/Ryomasao/sample_basic_css.git (fetch)
origin  https://github.com/Ryomasao/sample_basic_css.git (push)

あとは、githubにpushするのと同じ要領で

$ git push heroku master

デプロイが完了しました。

先ほどの「https://sample-basic-css.herokuapp.com/」にアクセスすると、Webサイトが参照できました!

ラズパイで工作記事まとめ

ラズパイ電子工作の記事がとっちらかってきたので、ここに書くことにしました。

ラズパイZero初期設定

ラズパイZeroを購入して、PythonでGPIO操作をするまでの記事になります。
RaspBerry Pi Zeroの初期設定メモ - 豆腐とコンソメ ラズパイZeroでWringPiが使えるまでメモ - 豆腐とコンソメ WiringPiでエラーになった場合のメモ - 豆腐とコンソメ

電子工作の基礎知識

電子工作をする上で、気になったことを書いた記事になります。
LEDを光らせるのは、電子工作界のHelloWorldらしいです。

RaspBerryPiではじめる電子工作まとめ:電気ってなんだろう - 豆腐とコンソメ 電圧やら、なんやらを計測してみた:テスターの使い方 - 豆腐とコンソメ LEDを正しく光らせる - 豆腐とコンソメ

モーターを動かす

ラズパイ3を使って、PythonでGPIO操作を用いてモーターを動かしたときの記事になります。
RaspBerryPiでモーターを動かす(1) - 豆腐とコンソメ RaspBerryPiでモーターを動かす(2) - 豆腐とコンソメ

ラジコンを動かす

ラズパイを用いてラジコンカーを作成するまでの記事になります。

以下は、ラズパイ側の電子工作の記事です。
RaspBerryPiでモーターを動かす(3):圧倒的力不足 - 豆腐とコンソメ
RaspBerryPiでモーターを動かす(4) - 豆腐とコンソメ
RaspBerryPiでモーターを動かす(5):だいぶ脱線 - 豆腐とコンソメ

この辺で、一回想定したものが完成しました。
RaspBerryPiでラジコンをつくる(6):とりあえず動くものができました - 豆腐とコンソメ

これは、ラジコンカーを操作することをPC画面から操作することを目的とした記事です。
RaspBerryPiでラジコンをつくる(8):コントローラをつくる - 豆腐とコンソメ

新しいレゴブロックを購入して、ラジコンカーをつくることにしました。
RaspBerryPiでラジコンをつくる(9):軽量化問題を解消するためのたったひとつの冴えたやり方 - 豆腐とコンソメ

ラジコンをブラウザから操作することにしました。
RaspBerryPiでラジコンをつくる(13):コントロール画面が完成した - 豆腐とコンソメ

ステッピングモーターを動かす

特に目的もなかったのですが、ステッピングモーターを動かした際の記事になります。

RaspBerryPiでステッピングモーターを動かす - 豆腐とコンソメ

アドホック接続

ラジコンをWifiがない環境で操作したかったので、書いた記事になります。
ラズパイをアドホック接続で使用する - 豆腐とコンソメ

RaspBerryPiでラジコンをつくる(13):コントロール画面が完成した

免許合宿の空き時間を利用して、ラズパイのラジコンのコントロール画面を作成してきましたが、一区切りついたのでまとめます。

ラズパイどうのこうのより、画面をつくるほうが大変だった!

つくったもの

コントロールする画面

画面のレイアウトに関してはBootstrap4.xを使用しました。
CSSの基礎は、使わないとすぐに忘れちゃいます。

今回は、スマホで見ることも意識して、レスポンシブを多少意識することにしました。

PC画面
f:id:konoemario:20170807223712p:plain:w500


スマホ画面(実際に映像をつけているところ)
f:id:konoemario:20170807223610p:plain:w500

コントロール画面でできることは、

  • カメラモジュールの映像を見る
  • レゴカーの前進、後退
  • 右折・左折(ただし、直進は実装していないというポンコツっぷり)
  • レゴカーのクレーンを動かすことによるカメラの視点変更
  • ラズパイと同じネットワーク内で使用する場合と、外部のネットワークから使用する場合の切り替え

になります。

ラズパイを外部のネットワークから参照するには、以下を参考にさせていただきました。

qiita.com

ssh接続自体は、秘密鍵が必要なのでまだいいのですが、Webサーバーには普通にアクセスできてしまうのが現状なので、勉強がてらログインページでも作成しようと思っています。

動くもの

こちらは、以前に紹介したレゴカー第2弾のものになります。

www.tohuandkonsome.site

レゴカー

f:id:konoemario:20170808222546j:plain:w500


前回と比較して、

  • ステアリングを実装するためのサーボモータをもう少しパワーのあるものにした
  • レゴカーそのものをパーツを外して軽量化した
  • カメラモジュールの延長ケーブルを購入して、レゴカーのクレーン部分につけた

などの変更を加えました。

カメラモジュール
f:id:konoemario:20170808223844j:plain:w500

コントローラー画面からクレーンを左右に操作することで、周囲の映像を見ることが可能になりました。

クレーンが動いているところ
f:id:konoemario:20170808224101g:plain

技術的なこと

こちらも、以前書いたことがありますが、改めて整理します。

www.tohuandkonsome.site

なんとなくの全体図 f:id:konoemario:20170719083402j:plain:w500

  • node.jsでコントロール画面を作成
  • コントロール画面からsocket.ioでFlaskのWebサーバーに接続し、前進・後退等の命令を送信
  • FlaskのWebサーバーがwiringpiでラズパイのGPIOをコントロール
  • ラズパイに「mjpg-streamer」をインストールして、カメラモジュールの映像をコントロール画面表示

コントロール画面:node.js

コントロールする画面は、node.jsを使いました。

node.jsにした理由は、socket.ioを使いたかったからです。

また、node.jsをそのまま使ってももちろんよかったのですが、なんとなくフレームワークのexpressを使うことにしました。

expressを使うことで、テンプレートエンジンという言葉にぶつかり、せっかくなのでjade(pug)を使うことにしました。

express、jadeに関しては、以下で触れました。

www.tohuandkonsome.site

www.tohuandkonsome.site

ただ、socket.ioに関してはPythonのFlaskでも普通に使えるみたいなので、コントロールする画面含め、全てFlaskで作ってもよかったです。

コントロールする画面に関しては、以下のリポジトリに管理しています。

github.com

自分のためにも、READMEはこれから更新します。

ラズパイのGPIOを制御する機能:Flask

こちらに関しても、以前触れたことがあるのであまり書くことがありません。

www.tohuandkonsome.site

機会があればDjangoでsocket.ioを使ってみたいです。

リポジトリは以下で管理しています。

こちらも、READMEを更新します。

github.com

Node.js + express + jade + Bootstrapに触れてみる

前回は、ラズパイのコントローラ用の画面をBootstrapを使ってざっくりとつくりました。

tohutokonsome.hatenablog.com

今回はその画面をnode.js + expressにのせるにあたってjadeというものが出てきたので、そちらを最初に触れたいと思います。

expressを使用するにあたって、テンプレートエンジンという単語がでてきます。
テンプレートエンジンという単語そのものの意味は置いておいて、私の理解としては動的コンテツを提供する際に、pythonDjangoだったり、PHPだったりHTML内にスクリプトを埋め込んで、サーバー側が解釈したHTMLをクライアントに返す、そのサーバー側が解釈する際のミドルウェア?を指していると思ってます。

Djangoで言うと以下のようなやつ。

    <h3> {{ post.title }}</h3>

expressでもテンプレートエンジンをいくつか選べるのですが、その中でもjadeというものを今回使ってみたいと思います。

ただ、jadeはhtml内に埋め込むお作法どうのこうの以上に、その記法そのものもhtmlとは異なっています。

とはいえ、その目的は生産性をあげるためのものなので、覚えてしまえばきっと楽になるはずです。

ケルトン作成

なにはともあれ、expressのスケルトンを作成します。
前回もやったので大丈夫です。

$ mkdir legocar_express
$ cd legocar_express
$ express
$.
├── app.js
├── bin
├── node_modules
├── package.json
├── public
├── routes
└── views


expressに必要なパッケージインストールします。

$ npm install

とりあえずさわってみる

素敵なチュートリアルがあるので、これに沿ってやった。
Jade について。 · GitHub

とりあえず、練習用にviews配下に以下のファイルを新規で作成した。

practicejade.jade

doctype html
html
  head
    meta(charset='UTF-8')
    title 最高にクールなホームページ
    link(rel='stylesheet', href='./css/app.css')
  body
    h1 最高にクールなホームページ
    p 最高にクールなホームページへようこそ。
    script(src='./js/app.js', charset='UTF-8')


表示するために、既存のindex.jsを修正する。

index.js

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index', { title: 'Express' });
});

/*jade練習用のページ */
router.get('/practicejade', function(req, res, next) {
  res.render('practicejade');
});

module.exports = router;

これで、「http://localhost:3000/practicejade」にアクセスすると、以下のページが表示される。

これをもとにチュートリアルを行う。

ちなみに、スケルトン作成時に特に指定したわけではないけれども、テンプレートエンジンはjadeになっていたので、こちらに関しては特に変更はしていない。

app.js(抜粋)

app.set('view engine', 'jade');


expressから渡したオブジェクトの値を参照する

jadeの基本的な構文については、チュートリアルに詳しく書かれているので、ここでは詰まったりした部分について記載していく。

まずは、表題の通り、html側で動的に値を表示したい場合とかの一例について。

index.jsファイルの中で定義したオブジェクト「pakage」をrender関数の引数として渡している。

index.js

/*jade練習用のオブジェクト */
var package = {
  title: '最高にクールなホームページ',
  description: '最高にクールなホームページです。見ないと損です。',
  keywords: [
    '最高',
    'クール',
    '世界一',
    '天才'
  ],
  robots: [
    'INDEX',
    'FOLLOW',
    'NOODP',
    'NOYDIR',
    'NOARCHIVE'
  ]
};

/*jade練習用のページ */
router.get('/practicejade', function(req, res, next) {
  res.render('practicejade',{package:package});
});


jade側では、渡されたpackageオブジェクトの値は下記のように参照することができるみたい。
いろいろな書き方があって混乱した。

practicejade.jade

doctype html
html
  head
    meta(charset='UTF-8')
    title 最高にクールなホームページ
    link(rel='stylesheet', href='./css/app.css')
  body
    h1 最高にクールなホームページ
    p 最高にクールなホームページへようこそ。

    h1 Expressから渡されたオブジェクトを参照する
    //いろいろな書き方がある。どれがいいんだろう。
    p #{package.title}
    p= package.description
    p!= package.keywords

    script(src='./js/app.js', charset='UTF-8')


ブラウザの表示
f:id:konoemario:20170730155847p:plain:w500


コレクション要素を表示する

表題があっているか少し怪しい。

さきほどの例のように、要素をひとつずつ表示するのではなく、リスト形式のように並べたいときにforeach構文が使える。

もちろん、for loopみたいなものをあるんだけれども、each構文で詰まったのであえてこちらを記載しておく。

ただ、あんまりしっくり来てないので、Quitaの方で詳しい方からのツッコミ待ちの状態です。

qiita.com

とりあえずコードの中身と表示結果を記載しておく。

practicejade.jade

doctype html
html
  head
    meta(charset='UTF-8')
    title 最高にクールなホームページ
    link(rel='stylesheet', href='./css/app.css')
  body
    h1 最高にクールなホームページ
    p 最高にクールなホームページへようこそ。

    hr
    h1 each構文を使う
    ul
    //inに直接オブジェクトを記載すると、コンパイルエラーになる。
      一旦、変数として定義してあげると問題ない。
      each val,key in #{package}
        li= key + ':' + val
  
    -var hoge = package
      each val,key in hoge
        li= key + ':' + val


ブラウザの表示
f:id:konoemario:20170730160502p:plain:w500


include

htmlファイルを部品化しておいて、使う側でinlucdeすることで再利用ができる、みたいなやつ。

新たに、includeディレクトリを作成して、その配下に「include_test.jade」を作成した。

├── include
│   ├── include_test.jade
├── practicejade.jade


部品化したファイル側にも#{変数名}の構文は使えるかな、という確認も込めて、package.titleを入れている。

include_test.jade

h3 これは、読み込んだincludeされたファイルです。 #{package.title} 


「practicejade_.jade」で上記のファイルをincludeします。

practicejade.jade

doctype html
html
  head
    meta(charset='UTF-8')
    title 最高にクールなホームページ
    link(rel='stylesheet', href='./css/app.css')
  body
    h1 最高にクールなホームページ
    p 最高にクールなホームページへようこそ。
    script(src='./js/app.js', charset='UTF-8')

    //includeのテスト
    h1 includeを使う
      include ./include/include_test.jadek


ブラウザの表示
f:id:konoemario:20170730161009p:plain:w500

extends

オブジェクト指向のインタフェースっぽいという印象を受けた。
extendで大まかなテンプレートを定義しておいて、includeする側で具体的な処理だったりを書くみたいな。

まず、extendされる「exten_test.jade」を作成する。

├── include
│   ├── include_test.jade
│   ├── extend_test.jade
├── practicejade.jade

ファイルの内容は、以下の通り。

extend_test.jade

doctype html
html(lang='ja')
  head
    meta(charset='UTF-8')
    title #{package.title}
  body
    block content
              p 上書きされるのでこれは表示されない。

これを、practicejade.jadeでextendsをして継承している。

practicejade.jade

//extend_test.jadeを継承する
extends ./include/extend_test
//extend_test.jadeのcontent部分を上書きする。
block content
    h1 Expressから渡されたオブジェクトを参照する
    //いろいろな書き方がある。どれがいいんだろう。
    p #{package.title}
    p= package.description
    p!= package.keywords


    hr
    h1 each構文を使う
    ul
    //inに直接オブジェクトを記載すると、コンパイルエラーになる。
      一旦、変数として定義してあげると問題ない。
      each val,key in #{package}
        li= key + ':' + val
  
    -var hoge = package
      each val,key in hoge
        li= key + ':' + val

    hr
    //includeのテスト
    h1 includeを使う
      include ./include/include_test.jade

Bootstrapを準備する

jadeの記法を使って、BootstrapのStarter Templateを作ります。

Bootstrap4.xのStarter Template

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
  </head>
  <body>
    <h1>Hello, world!</h1>

    <!-- jQuery first, then Tether, then Bootstrap JS. -->
    <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
  </body>
</html>

ファイル作成

viewsディレクトリ配下に、以下のファイルを用意しました。

├── include
│   ├── footer.jade
│   ├── header.jade
│   └── scripts.jade
├── index.jade
├── layout.jade

まずはextendsされるlayout.jadeです。

layout.jade

doctype html
html(lang='ja')
    head
        meta(charset='utf-8')
        meta(name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no")
        link(rel='stylesheet', href='/stylesheets/style.css')
        //Bootstrap ラズパイに乗せる時はCDNは使わないようにしたい
        link(rel='stylesheet',href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css' integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous")
        block title
    body
        include ./include/header
        block content
        include ./include/footer
        include ./include/scripts
  • head内のtitleおよびbody内のcontentはextendsする側で再定義します。
  • body内の「header」「footer」およびBootstrapに必要なjQueryを書くjavascriptは全ページ共通ということで、layout.jade内でincludeしています。

また、index.jadeの内容は以下の通りとなります。

index.jade

extends ./layout
block title
  title レゴカー
block content
  h1 Hello World!


ブラウザでみた場合
f:id:konoemario:20170730190403p:plain:w500

以上で、node.js + express + jadeでBootstrapを使用したページを作成する準備が整いました。

次回は、前回のリモコンの画面をjadeで書いていきたいと思います。

RaspBerryPiでラジコンをつくる(12):もう少しブラウザから操作する

以前、ブラウザからキー入力した情報をsocket.ioを使用してFlaskで作成したWebサーバーに送信する、というところまでやりました。

tohutokonsome.hatenablog.com

ラジコンとしては、最低限の機能を有しているわけですが、もうすこし画面に凝ってみたい、スマホからの操作も意識してみたい、というところもありまして、画面を作成することにしました。

このブログを始めた当初に、日めくりカレンダーを作ってみよう、という中途半端なもの作成した際に、HTMLとCSSの勉強を少ししたのですが、もう忘れてしまっていました。

tohutokonsome.hatenablog.com

あまり作業メモを取っておらず後悔しましたので、今回はちゃんとメモっておこうと思います。

全般的に役に立つ内容はほとんどなく、自分のメモという側面が大きいです。
(あれ、このブログで役に立つことなんてあったけ?)

使用したHTMLエディタ

node.jsの時にはWebStromを使っていたので、こちらを使いたかったのですがお試し期間が終わっちゃいました。
ライセンスを購入したいところなんですが、とり急ぎVsCodeで作業することにしました。

VsCodeのプラグインはこちらを参考させていただきました。
qiita.com


さっそく作成する

とりあえず、socket.ioやらなんやらは忘れて、純粋にhtmlとcssのみ使っていきます。

Bootstrap公式のテンプレートをとってくるところからやろうと思ったのですが、わかりやすい記事がありましたので、以下を参考にしました。

Bootstrap3.x.で何かやるときの最低限のメモ - Qiita

ただ、今回使用するBootstrapのバージョンは4.xにしました。

とりあえず最初にグリッド

参考記事をそのまま真似ています。

てきとうなhtml

<!DOCTYPE html>
<html lang="ja">
  <title>LegoCarコントローラ</title>
  <head>
    <!-- Required meta tags -->
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">

    <!-- Bootstrap CSS -->
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
  </head>
  <body>


<div class="container">
    <!-- header -->
    <div class="row">
    <div id="header" style="background-color:#ff0000">header</div>
    </div>

    <!-- content -->
    <div class="row" style="background-color:#00ff00">
        <div class="col-md-3">left</div>
        <div class="col-md-6">center</div>
        <div class="col-md-3">right</div>
    </div>

    <!-- footer -->
    <div class="row">
    <div id="header" style="background-color:#0000ff">footer</div>
    </div>
</div>

    <!-- jQuery first, then Tether, then Bootstrap JS. -->
    <script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
  </body>
</html>


ブラウザでみた場合
f:id:konoemario:20170726111013p:plain:w500

参考記事のBootstrap3.xでは、上記でいい感じに幅が揃っていたのですが。headerとfooterがはみ出てしまいました。
どうもBootstrap4.0の影響っぽいです。

選択肢として、カラムの値を12にすればできたけれども、違和感があります。

    <!-- header -->
    <div class="row">
           <div class="col-md-12" style="background-color:#ff0000">header</div>
    </div>

今回、全体をcontainerで囲む必要性を感じなかったので、メインコンテツ部分のみをcontainerで囲むことにしました。

てきとうなhtml(抜粋)

    <!-- header -->
    <div id="header" style="background-color:#ff0000">header</div>

    <div class="container">
        <!-- content -->
        <div class="row" style="background-color:#00ff00">
            <div class="col-md-3">left</div>
            <div class="col-md-6">center</div>
            <div class="col-md-3">right</div>
        </div>
    </div>
        <!-- footer -->
    <div id="header" style="background-color:#0000ff">footer</div>


ブラウザでみた場合
f:id:konoemario:20170727132424p:plain:w500


ヘッダーを編集する

やっぱり、ヘッダーにナビゲーションっぽいものがあるといいのかな、ということでnavbarをつけます。

navbarに関しては、公式のほぼそのままです。

Navbar · Bootstrap

さきほどのheader部分をまるっと以下に置き換えます。

てきとうなhtml(抜粋)

<!-- headerはnaviだよ -->
    <nav class="navbar  navbar-toggleable-md navbar-inverse bg-primary">
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

      <!--Brandはnavbar-brand -->
      <a class="navbar-brand navbar-inverse" href="#">tohu</a>

      <!--navの要素-->
      <div class="collapse navbar-collapse" id="navbarNav" >
        <ul class="navbar-nav">
          <li class="nav-item">
            <a class="nav-link" href="#">要素1</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">要素2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">要素3</a>
          </li>
        </ul>
      </div>
    </nav>


ブラウザでみた場合
f:id:konoemario:20170727160354p:plain:w500

せっかくなので、上部に固定します。
navのclassにfixed-topを追加しました。

てきとうなhtml(抜粋)

    <!-- headerはnaviだよ -->
    <nav class="navbar  navbar-toggleable-md navbar-inverse bg-primary fixed-top">
      <button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>

      <!--Brandはnavbar-brand -->
      <a class="navbar-brand navbar-inverse" href="#">tohu</a>

      <!--navの要素-->
      <div class="collapse navbar-collapse" id="navbarNav" >
        <ul class="navbar-nav">
          <li class="nav-item">
            <a class="nav-link" href="#">要素1</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">要素2</a>
          </li>
          <li class="nav-item">
            <a class="nav-link" href="#">要素3</a>
          </li>
        </ul>
      </div>
    </nav>

また、例のごとくfixed-topで固定した分、メインコンテンツをnavbarの高さ分paddingします。

どれくらいpaddingしていいかは、公式サンプルを参考にしました。

Fixed top navbar example for Bootstrap

    <style>
        /* Show it is fixed to the top */
        body {
        /*min-heightはスクロール検証用*/
          min-height: 75rem;
          padding-top: 4.5rem;
        }
    </style>


ブラウザでみた場合
f:id:konoemario:20170727160605p:plain:w500

作成する画面イメージ

ここに来て、手がとまっちゃいました。
というのも、どんな感じの画面をつくるのかをあまり考えていなかった!

とりえあえずのイメージをdraw.ioで書いてみました。


作成する画面イメージ
f:id:konoemario:20170727210800j:plain:w500

右側に広大なスペースがありますが、あまったら畑でも耕しておけばいいと思うので、とりあえずこんな感じでいきます。


メインコンテンツ

とりあえずメイン部分となる、カメラの映像の部分と、コントローラーの部分をつくっていきたいと思います。

メインは、カメラ、コントローラ部分と畑部分とで2カラムとしますので、以下のようにしました。

てきとうなhtml(抜粋)

    <div class="container">
        <!-- content -->
        <div class="row" style="background-color:#00ff00">
             <!--カメラとコントローラー-->
            <div class="col-md-9" style="background:red">main</div>
            <!--未開拓地域-->
            <div class="col-md-3" style="background:yellow">side</div>
        </div>
    </div>


ブラウザでみた場合
f:id:konoemario:20170727161728p:plain:w500


カメラ部分

ラズパイのカメラの映像はお馴染みの「mjpg-streamer」を使っています。
なので、ストリミーング映像は、以下のimgタグを使うことで簡単に表示できます。

    <img src="http://ラズパイのIPアドレス:8080/?action=stream">

ストリーミング映像のサイズは、mjpg-streamerのオプションで設定しています。
今は、「240 X 320」で設定しているのでそのサイズを意識することにしました。

てきとうなhtml(抜粋)

            <!--カメラとコントローラー-->
            <div class="col-md-9" style="background:red">
                <div id="monitor-wrapper">
                  <div id="monitor">
                      <!--とりあえず適当な画像を置いておく-->
                      <img src="https://placehold.jp/240x320.png">
                  </div>
                </div>

styleは以下のようにしました。

        #monitor-wrapper{
            padding-left:30px;
        }

        #monitor > img {
            transform: rotate(90deg);
        }

とりあえず、こんな感じになった。


ブラウザでみた場合
f:id:konoemario:20170727213011p:plain:w500

「monitor-wrapper」やらimgタグでrotateしているのはラズパイのカメラの取り付けの際にカメラの向きが90度右になった状態で設置してしまったので、それを補正するために対応した。

自宅のカメラを直せば、こんなことをしなくてよいのだけれども、免許合宿先で作業しているため、仕方がない。

コントローラ部分

ボタンを4つ十字に並べるだけといわれれば、それだけなんだけれども、それだけをどうやってやればいいのかなぁと悩んだ。

結果、flexboxと呼ばれるCSSレイアウトを使うことにした。

coliss.com

とりあえず、以下のように3 X 3のマスの上にButtonを並べるイメージで考えることにして、Button以外の要素は背景色に同化させて見えないようにした。

3X3のマスにボタンがあるイメージ
f:id:konoemario:20170727214246p:plain:w500

てきとうなhtml(抜粋)

            <!--カメラとコントローラー-->
            <div class="col-md-9" style="background:red">
                <!--カメラ-->
                <div id="monitor-wrapper">
                  <div id="monitor">
                      <img src="https://placehold.jp/240x320.png">
                  </div>
                </div>
                <!-- コントローラー-->
                <div id="controller_wrapper">
                    <div class="dummy_button"></div>
                    <button class="controller_button">前進:W</button>
                    <div class="dummy_button"></div>
                    <button class="controller_button">左折:A</button>
                    <div class="dummy_button"></div>
                    <button class="controller_button">右折:D</button>
                    <div class="dummy_button"></div>
                    <button class="controller_button">後退:S</button>
                    <div class="dummy_button"></div>
                </div>

styleは以下とした。

        /*flexさせたい要素の親要素のdisplayとして設定する。*/
        #controller_wrapper{
            background: #42aaf4;
            width:300px;
            height: 150px;
            display: flex;
            flex-direction: row;
            flex-wrap: wrap;
        }

        .controller_button{
            margin: 1%;
            padding: 0;
            width:30%;
            height:30%;
            background: #c97796;
            text-align: center;
            color: white;
            border-radius: 10px;
        }

        .dummy_button{
            margin: 1%;
            padding: 0;
            width:30%;
            height:30%;
        }


ブラウザでみた場合
f:id:konoemario:20170727215055p:plain:w500

申し訳程度にフッターをつける

フッターがあるとそれっぽいかなぁということで、フッターをつけることにした。

Bootstrap公式のフッターをそのままもってくる。

Sticky Footer Template for Bootstrap

てきとうなhtml(抜粋)

    <!-- footer -->
    <footer class="footer">
      <div class="container">
        <p class="text-muted"><a href="http://tohutokonsome.hatenablog.com/archive">豆腐とコンソメ</a></p>
      </div>
    </footer>

スタイルもそのまま。

        /* Sticky footer styles
        -------------------------------------------------- */
        html {
          position: relative;
          min-height: 100%;
        }
        body {
          /* Margin bottom by footer height */
          margin-bottom: 60px;
        }
        .footer {
          position: absolute;
          bottom: 0;
          width: 100%;
          /* Set the fixed height of the footer here */
          height: 60px;
          background-color: #f5f5f5;
        }


ブラウザでみた場合
f:id:konoemario:20170728175930p:plain:w500

なかなかひどいデザインです。 もう動かしたい!という気持ちがでてきちゃっているので、先に使えるようしてからデザインを整えたいなぁと思っとります。

次回は、これをnode.jsのプロジェクトにのっけていきます。

指導員に腹が立つ:免許合宿3日目

30歳の無職期間を生かして、人生で2度目の免許講習を受講しております。

学科の講義は、DVDの映像で出てきたことを、再度指導員が説明し直したり、開いているページを読めば5分で終わることを15分かけて説明しています。

お金もそうなんですが、時間の取られ方が半端ない、と思う今日この頃です。

免許合宿で参加しているのですが、同日に合宿に参加した方々ともトランプをしたりと、すこし馴染んだかなと思います。

が、ここにきて、一緒に行動しなきゃいけない感がでてきていて、ちょっと煩わしくなってきてしまった今日このごろです。

この年齢で何を気にしているんだろうということで、もっと自由に行動したいと思います。

tohutokonsome.hatenablog.com

さて、免許合宿ということで初日から実技として車の運転をしております。

が、前回もそうだったのですが、この実技の時間、心が痛いです。
顔にはあまりださないようにしているのですが、腹が立つこともありますし、凹むこともあります。

指導員の方にもよるのですが、嫌な気持ちになることの方が圧倒的に多いので、いわれて頭にきた、つらかった言葉を書き起こしました。


「焦らなくていいから落ち着いてやって」

文字に起こすと、当たり前のことですね。

ただ、焦らなくていい、といわれてすぐ落ち着ける人間がどれくらいいるのでしょうか。
もとより、それを言う側の言葉に感情が少しでも乗っかっていると、余計焦ります。

そもそもなぜ僕が焦っている原因はなんなんでしょうか。
例えば、教習所内でいらないアクセルを踏んでいて、スピードを出ているせいで、慌ただしくなっているのか、過剰にエンストを恐れていて、クラッチをやけに踏んでて無駄な操作が多いとか、そもそも情報過多で混乱しているのか、とかいろいろあるわけです。

そこを一切無視して、焦るなと言われても何も改善しないです。


「もっと集中して」

気を抜いているわけでもなく、真剣にやっているときに、集中しろっていわれるとなんだかなぁと思います。


「 こういうところに気をつけないとすぐ事故になるよ!」

事故をおこしたいわけでも、面倒だから省略してるわけでもなんでもなく、只々慣れていないだけなんです。
このセリフの意図はある種、脅すことによっての学習効果を期待しているのかもしれませんが、メンタルが弱い自分にとってはひどく逆効果です。


思うこと

自分のメンタルの弱さもあるのですが、基本的に、感情を乗っけられた指摘というのは、自分を否定されたような気がしてつらいです。

なので、やっぱり褒めていただきたいです。

ああ、褒められたいです。

思い返せば、テスト用紙を目の前で採点されるとかも苦手でしたし、前職でシステム障害時の解析とかしている最中に、後ろに立たれるのはすごく嫌でした。

根本的な部分を改善できればと思うのですが、こんな自分でも相性のよい指導員の方はいたりするので、人を選べればなぁと思います。

先が思いやられます。

30歳の無職が免許合宿に参加した:一日目

日記

30歳を目前にして、合宿免許入校日を迎えました。

送迎バスの隣の若人たちは、「どこの大学?俺、今2年目だよ。」という会話をしており、交わりたいけれども、その話は振って欲しくないなぁ、と自意識過剰な思いでバスに揺られていました。

教習所の印象は、以前免許を取得した際と同じで、あまりいいものではありません。

事前に送付しろといわれて、送付した入学申込書やら誓約書やら適正チェックシートやらを入学初日になぜ再度書く必要があるんだろうとか、手書きのマークがやたら書き込まれた講義予定簿やら、なくすと最初からやり直しといわれる(さすがに脅しですよね、、、?)履修管理シートやらいろいろと残念です。

とはいえ、いろんな層の方が受講する講義なので、あんまりやり方を変えたくない(そもそも必要も変える必要がない)っていうところなのでしょうか。

金髪の集団が怖いです。

喧嘩で退校になった旨のポスターとかが貼ってあったりして、トイレに行くのも怖いです。

ただ何より残念なのが、免許の更新し忘れで、失効した免許をとるべく、時間もお金もそれなりにかかるこの講習を受けている自分の頭です。

同日に入校となった方達は皆大学生でした。

免許合宿だと同日に入校する人たちはある程度グループになる傾向があるみたいです。

お昼をご一緒させていただきました。

いつ、僕は無職で30歳なんだ!とカミングアウトしようかと悩んでいたのですが、なかなか言う機会を見つけられないまま、「ハハッ、サークルとか何かやってるのかい?」とかお茶を濁している間に、入校の手続きが始まってしまいました。

しかし、罠は入校の手続きにありました。

手続きの中で、係の方が、「みなさん、保険証を出してください」と言っているじゃないですか。

保険証が必要なんてどこにも書いてなかったはず、保険証は、切り替え手続きの最中で手元にないぞ、といろいろとテンパっていました。

また、提出書類には、悪しき「学校名または会社名」という欄があり、ぐぬぬ、と筆がとまりました。

仕方がないので、「無職なので保険証を持ってきていません、会社名の欄には何を書けばいいですか?」と正直に告白しました。

僕の合宿免許生活はもう終わってしまうのでしょうか。