【Arduino】Arduino Nano(互換機)+人感センサ+サーボモータでトイレを灯す

前回の続きです。

engetu21.hatenablog.com

前回は人感センサに反応してLEDを付けるようにしていましたが、サーボモータに変更して電灯スイッチのON/OFFを実現します。

一応ですが、こんなものを作らなくても人感センサ付きLED電球もありますよ。(実際一個持ってますが、今の住居では口径が合わないために使う場所がない)
my-best.com

1.構成と回路図

構成図はこんな感じ。
f:id:engetu21:20190522234215p:plain

Arduinoの信号ピンはD12を使います。
サーボモータはSG-90。
こいついつもこれ使ってんなって感じですが、なんせ5個セットで買ってるからね。
akizukidenshi.com


回路図はこんな感じ。信号線はわかりやすいように青色、+線は赤、ー(マイナス)線は黒にしてみました。
f:id:engetu21:20190522231049p:plain

2.プログラム

前回からの変更点として、サーボモータを動かす関数を新たに設けてます。あと、setup()内の「// 無条件で初回は点灯」の部分は、変数間違えてたのでそこも修正して、検知は1秒⇒0.5秒間隔に変更。
サーボモータ用の12ピンは定数にすべきだったけど、まぁいいや。
大体これで動きます。

#include <Servo.h>  //サーボモーター用ライブラリを読み込み

#define LED_PIN 3
#define PIR_PIN 8

int sonzai = 0;        // 存在フラグ
int tentouzumi = 0;    // 点灯フラグ
double count = 0;       // 秒数カウンター

//////////// サーボモータ設定 /////////////
Servo myservo; //サーボ用のオブジェクトを作成
int val; //サーボの角度を格納するための変数
//////////////////////////////////////////

// the setup function runs once when you press reset or power the board
void setup() {
  // initialize digital pin LED_BUILTIN as an output.
  pinMode(LED_PIN, OUTPUT);
  pinMode(PIR_PIN, INPUT_PULLUP);
  //Serial.begin(9600); 

  //tentouzumi = 1;      // 無条件で初回は点灯
  sonzai = 1;
}

// the loop function runs over and over again forever
void loop() {
  
  delay(500);         // 0.5秒間スリープ
  count = count + 0.5;   // カウントアップ
  analogWrite(LED_PIN, 0);

  // 30秒後に判定
  if (count == 30){
    
    count = 0;                // カウンターリセット
    //Serial.println("30秒目の判定!");
    //Serial.println(sonzai);
    //Serial.println(tentouzumi);
  
    // 点灯しており、かつ誰も居ない時
    if (tentouzumi == 1 && sonzai == 0){

      // 明かりを消す
      servoSwitchOff();

      tentouzumi = 0;  // 点灯済みフラグをクリア
    }
    
    sonzai = 0;        // 存在フラグをクリア
    
  }
  
  //0.5秒ごとに判定
  if (count < 30){
    //Serial.println(count);
    //Serial.println(sonzai);
    //Serial.println(tentouzumi);

    // 点灯しておらず、かつ誰か居る時
    if (tentouzumi == 0 && sonzai == 1){

      // 明かりを付ける
      servoSwitchOn();

      tentouzumi = 1;     // 点灯済みフラグをONに
      count = 0;          // カウンタリセット

    }

  }
  
  // センサに反応があった場合(誰か居る場合)
  if (digitalRead(PIR_PIN) == HIGH){
      sonzai = 1;         // 存在フラグをONに
      analogWrite(LED_PIN, 20);
  }
}

//////////// サーボモータ動作 /////////////
void servoSwitchOn() {
        myservo.attach(12); //デジタル12番ピンをサーボの角度命令出力ピンとして設定

        val = 0;

        // サーボモータ実行
        for(int i=90; i<=130; i++){
          val = i;
          myservo.write(val);
          delay(15);
        }
        for(int i=130; i>=90; i--){
          val = i;
          myservo.write(val);
          delay(15);
        }
        myservo.detach();
}

void servoSwitchOff() {
        myservo.attach(12); //デジタル12番ピンをサーボの角度命令出力ピンとして設定

        val = 0;

        // サーボモータ実行
        for(int i=90; i>=70; i--){
          val = i;
          myservo.write(val);
          delay(15);
        }
        for(int i=70; i<=90; i++){
          val = i;
          myservo.write(val);
          delay(15);
        }
        myservo.detach();
}
//////////////////////////////////////////

なかなか角度の調整が難しかったので、トイレを行ったり来たりする羽目に。こういうところはやってみないとわからないですなぁ。

3.設置

追加したサーボモータは両面テープでスイッチの下にくっつける。
サーボモータのプロペラ(?)はスイッチの大きさに合わせて削りました。
f:id:engetu21:20190522231446j:plain

Aruduino Nanoを入れた箱。自作。ワイシャツ買ったので、それに入っている型崩れ防止用の厚紙がいい感じに余ってたので、ノリで組み合わせて紙テープを張りました。意外とよくできてる。蓋も作ってます。
f:id:engetu21:20190522231405j:plain

検知すると光ります。
f:id:engetu21:20190522231412j:plain

実際には箱の中に設置した青色LEDの光が投下されてるだけです。
f:id:engetu21:20190522231744j:plain

蓋取った時の箱の中身。箱の下に穴をあけてUSBケーブルを通してます。
f:id:engetu21:20190522231427j:plain

【Arduino】Arduino Nano(互換機)で人感センサ付けてLEDを光らせる

久しぶりに電子工作をやります。
やりたいこととして、トイレの電灯を人がいれば点灯(電灯スイッチON)、いなければ消灯する(電灯スイッチをOFF)です。
これは最終的にサーボモータを組み合わせて実現するとして、試作として人がいると検知したらLEDを灯すのをメモとして残します。

1.使用パーツ

 ↓たぶんこれ?(数年前に買ったものなので、厳密にはたぶん違う)
 Rasbee Mini USB Arduino Nano V3.0 改良版 互換ボード ATmega328P搭載 1個 [並行輸入品] http://ur0.work/Wp9b

  • ブレッドボード
  • ジャンパーワイヤ
  • RIPモーションセンサ

 ↓たぶんこれ?((数年前に買ったものなので、厳密には違う。私が持っているものはピンの詳細が基盤に印字されてないので、どれかGNDとかわからなかったり)
 超小型赤外線センサーモジュール人体感知スイッチhttp://ur0.work/9Vq7

2.構成イメージと回路図

まぁこんな感じです。

f:id:engetu21:20190511202135p:plain
f:id:engetu21:20190511202210p:plain

RIPセンサーの信号はD8を利用、LEDに関してはD3を使います。
D3を使うのはプログラムで「analogWrite関数」を使いたいためです。
なぜ「analogWrite関数」を使いたいかというとLEDの明るさを小さくしたいためです。

Arduino Nanoの仕様は以下の図の通りですが、D3、つまり3ピン(紫で3の箇所)についてはPWM Pinと記載されています(線のところが~となっており、凡例を見るとこれがPWM Pinを表す)。
f:id:engetu21:20190511202711p:plain
D3にLEDのアノードを刺すことで明るさを小さくしたり大きくしたり。for文を用いれば、ゆっくり明るくするといったことも可能です。
※詳しくはこちら
明るさを変化させてみよう(PWMでアナログ出力):
http://jkoba.net/prototyping/arduino/led_brightness.html

実際の構築はこんな感じ。
f:id:engetu21:20190511203716j:plain

3.プログラム

#define LED_PIN 3
#define PIR_PIN 8

int sonzai = 0;        // 存在フラグ
int tentouzumi = 0;    // 点灯フラグ
int count = 0;         // 秒数カウンター

void setup() {
  pinMode(LED_PIN, OUTPUT);
  pinMode(PIR_PIN, INPUT_PULLUP);
  Serial.begin(9600);

  tentouzumi = 1;      // 無条件で初回は点灯
}

void loop() {
  delay(1000);         // 1秒間スリープ
  count = count + 1;   // カウントアップ

  // 30秒後に判定
  if (count == 30){
    count = 0;                // カウンターリセット
    Serial.println("30秒目の判定!");
    Serial.println(sonzai);
    Serial.println(tentouzumi);
  
    // 点灯しており、かつ誰も居ない時
    if (tentouzumi == 1 && sonzai == 0){

      // 明かりを消す
      analogWrite(LED_PIN, 0);
      Serial.println("off");

      tentouzumi = 0;  // 点灯済みフラグをクリア
    }
    sonzai = 0;        // 存在フラグをクリア
  }
  
  // 満期に達してない場合
  if (count < 30){
    Serial.println(count);
    Serial.println(sonzai);
    Serial.println(tentouzumi);

    // 点灯しておらず、かつ誰か居る時
    if (tentouzumi == 0 && sonzai == 1){

      // 明かりを付ける
      analogWrite(LED_PIN, 1);
      Serial.println("on");

      tentouzumi = 1;     // 点灯済みフラグをONに
      count = 0;          // カウンタリセット
    }
  }
  
  // センサに反応があった場合(誰か居る場合)
  if (digitalRead(PIR_PIN) == HIGH){
      sonzai = 1;         // 存在フラグをONに
  }
}

大体これで動く。
満期は30秒とし、その際誰もいなければ消灯、一秒間隔の監視で誰かいたら点灯。
実際のところ、これは昔書いたラズパイ版のソースの流用です。
engetu21.hatenablog.com

電灯スイッチをサーボモータで押すため、サーボモータの動作時間を考えると一秒間隔よりもっと短く検知させ、すぐ電灯がつくようにしたほうがいいかもしれない。

そういえば、Arudino Nanoに関してはUSB(mini Type B)でPCと接続することでプログラムのライティングができる。これは互換機も同様。
Arduino IDEの設定としては以下のようにすれば設定すれば書き込みができた。
f:id:engetu21:20190511212327j:plain

なお、USB-ACアダブターをつなげて直接電源供給が可能なため、電源周りのセッティングはとても楽。

次回は今回の構成とプログラムにサーボモータを付けるようにして電灯スイッチを押させるようにします。

【Raspberry Pi】ラズパイ3でOKグーグルする

ラズパイ3でOKグーグルしてみます。
developers.google.com

なお、英語は読めないので、ところどころGoogle日本語翻訳機能を使って日本語化してます。

1.ラズパイ3の準備

f:id:engetu21:20190505205007p:plain
ハードウェア毎の準備については、「ハードウェアとネットワークアクセスを設定する」を選択することで、確認することが可能。
最もラズパイに関しては、ここを見るよりは詳しい情報を見たほうがいい。(一応昔書いたけど)
engetu21.hatenablog.com
engetu21.hatenablog.com

2.プロジェクトの作成とAPIの有効化

f:id:engetu21:20190505211244p:plain
※事前にグーグルアカウントを用意しておいたほうがよいです。

手順にしたがって、アクションコンソールから操作を行います。
[アクションコントロールに移動します]を押下。


f:id:engetu21:20190505212154p:plain
新しく画面が開くため、[Add/import project]を押下。


f:id:engetu21:20190505212520p:plain
利用規約に同意します。下2つは最新情報受け取るかとかそんな感じ。


f:id:engetu21:20190505213052p:plain
プロジェクト名を設定。プロジェクト名はとりあえずデフォルト。日本人なので日本語と日本を設定。


f:id:engetu21:20190505213947p:plain
プロジェクトが作成されるとWelcomeページに飛ぶ。ページ一番下にある[Device registration]を押下する。


f:id:engetu21:20190505215017p:plain
押下すると上記のような画面に。とりあえずこの画面は後ほどいじりますが、今は放置。手順に戻ります。


f:id:engetu21:20190505215317p:plain
手順画面から[APIを有効にする]を押下。


f:id:engetu21:20190505215556p:plain
ページが新しく開くので、[有効にする]を押下することでAPIの設定が完了する。


f:id:engetu21:20190505215853p:plain
作成したプロジェクトにてAPIが使えるようになると上記の画面表示になる。
とりあえずこの画面も放置。


3.アクティビティ管理設定

手順からアクティビティ設定画面に飛ぶ。以下のリンクから飛んでもOK。
https://myaccount.google.com/activitycontrols?pli=1

OKグーグルをするには以下が有効になっていないといけないらしい。

・Webとアプリのアクティビティ
 さらに、Googleのサービスを使用するサイト、アプリ、端末のChromeの履歴とアクティビティを含めるチェックボックスを必ず選択してください。
・デバイス情報
・音声と音声のアクティビティ

とのこと。
いくつかのアクティビティを有効にするので、気になる人はOKグーグル用にアカウントを作ってもいいかもしれない。

f:id:engetu21:20190505223928p:plain

4.デバイス(ラズパイ3)の情報を登録する

https://developers.google.com/assistant/sdk/guides/library/python/embed/register-device
手順に従ってデバイスの登録を行います。


ここでは一旦放置していた↓の画面を利用します。
f:id:engetu21:20190505215017p:plain
[REGISTER MODEL]を押下。


f:id:engetu21:20190505224747p:plain
設定画面になるので、ひとまず適当に設定を行います。
[REGISTER MODEL]を押下。


f:id:engetu21:20190505225652p:plain
認証情報を自動で生成してくれるため、[Download OAuth2.0 credentials]を押下することで、JSONファイルをダウンロードすることができます。


f:id:engetu21:20190505230541p:plain
特性?については今のところは何も設定せず、[SKIP]を押下。


f:id:engetu21:20190505230817p:plain
作成が完了するとメニューにデバイスが表示される。
なお、うっかり認証情報(JSON)でダウンロードし忘れた場合は、デバイスの[・・・]からダウンロードできます。
あるいは、
https://console.developers.google.com/apis/credentials/consent
にアクセスしたあと、認証情報タブに移動し、「OAuth 2.0 クライアント ID」欄に作成した認証情報が追加されているため、そちらからダウンロードすることも可能です。


5.SDKとサンプルコードをインストール

https://developers.google.com/assistant/sdk/guides/library/python/embed/install-sample
ラズパイ3にて記載されている手順通りにコマンドを実行します。

python3とpipをすでに入れている場合は実行する必要はないかもしれない。

$ sudo apt update
$ sudo apt install python3-dev python3-venv
$ python3 -m venv env
$ ~/env/bin/python -m pip install --upgrade pip setuptools wheel
$ source ~/env/bin/activate

source ~/env/bin/activateを実行することで、コンソールに(env)が付くようになります。どうやら以降の作業で必須の模様。


パッケージをインストール

(env) $ sudo apt install portaudio19-dev libffi-dev libssl-dev libmpg123-dev
(env) $ python -m pip install --upgrade google-assistant-library==1.0.1
(env) $ python -m pip install --upgrade google-assistant-sdk[samples]==0.5.1


認証ツールをインストール

(env) $ python -m pip install --upgrade google-auth-oauthlib[tool]


次のコマンドにて4項でダウンロードしたJSONファイルが必要になります。
手順ではSCPコマンドでラズパイ3にファイルを渡す手順が記載されていますが、JSONファイルはテキストファイルなので、コンソール上でテキストファイルを作成、中身をコピペでも問題ありません。
ただし、ファイル名は全く同じものにする必要があります。
ファイルを置くのはpiユーザを使っている場合であれば/home/piでよいかと。(絶対パスで指定するので、実際どこでもいい)

(env) $ google-oauthlib-tool --scope https://www.googleapis.com/auth/assistant-sdk-prototype --scope https://www.googleapis.com/auth/gcm --save --headless --client-secrets /home/pi/client_secret_XXXXXXXXXXXXXX.json

実行すると、以下の形でURLが表示される。

Please visit this URL to authorize this application: https://accounts.google.com/o/oauth2/auth?response_type=code&client_id=***************

指定されたURLに関してはどの端末からアクセスしてもいい。コピペしてブラウザで開きます。
アカウントの選択画面が出るため、該当のアカウントを押下。

f:id:engetu21:20190505235438p:plain
権限の付与を許可。


f:id:engetu21:20190505235926p:plain
許可するとコードが発行されるため、これをコピーし、ラズパイのコンソールにて設定

Enter the authorization code: コピーしたコード

コードが承認されると以下のように表示され、JSONファイルが生成される(中身を見る必要は特に無い)

credentials saved: /home/pi/.config/google-oauthlib-tool/credentials.json

6.サンプルコードの実行

ラズパイ3上で以下のコマンドを実行する。

$ source ~/env/bin/activate
(env) $ googlesamples-assistant-hotword --project-id my-dev-project --device-model-id my-model

my-dev-projectの部分(プロジェクトID)は作成したプロジェクトから確認する必要があります。

https://console.actions.google.com/
まず、アクションコンソールにアクセス。

f:id:engetu21:20190506003728p:plain
作成したプロジェクトを選択し、左メニューの「Overview」の歯車をクリック、[Project setteings]を押下することで確認することができます。

また、my-modelの部分(モデルID)については、
f:id:engetu21:20190506004302p:plain
「Advanced Options」の[Device registration]を押下し、登録したデバイスを押すことで詳細画面を表示できるため、そこから「Model Id」を確認できます。
f:id:engetu21:20190506004705p:plain


実行に成功すると以下のように表示されます。

( ゚д゚)< OKグーグル
 
ON_CONVERSATION_TURN_STARTED
 
( ゚д゚)< Tell me the weather today(今日の天気を教えて)
 
ON_END_OF_UTTERANCE
ON_END_OF_UTTERANCE
ON_RECOGNIZING_SPEECH_FINISHED:
{"text": "tell me some results today"}
ON_RESPONDING_STARTED:
{"is_error_response": false}
ON_RESPONDING_FINISHED
ON_CONVERSATION_TURN_FINISHED:
{"with_follow_on_turn": false}

日本語発音のせいか、正常に認識はされない模様・・・。
また、スピーカーから喋ってくれないのを確認。これはあとで直すとしてとりあえず放置。

7.日本語音声入力に変更する

どうやら、日本語での入力に変更するにはAndroidGoogleアシスタントアプリから変更するらしい。

アプリを起動し、
f:id:engetu21:20190506005645p:plain
右上のアカウントアイコンから[設定]を押下


f:id:engetu21:20190506005732p:plain
アシスタントの[言語]を押下


f:id:engetu21:20190506005811p:plain
Englishになっているのを「日本語」に変更


OKグーグルと呼びかけると以下のようになります。

( ゚д゚)< OKグーグル
 
ON_CONVERSATION_TURN_STARTED
 
( ゚д゚)< 今日は何の日?
 
ON_END_OF_UTTERANCE
ON_END_OF_UTTERANCE
ON_RECOGNIZING_SPEECH_FINISHED:
{"text": "今日は何の日"}
ON_RESPONDING_STARTED:
{"is_error_response": false}
ON_RESPONDING_FINISHED
ON_RENDER_RESPONSE:
{"text": "5月6日、1970年のこの日、日本で改正著作権法が公布され、著作権保護が死後 50 年までになったそうです", "type": 0}
ON_CONVERSATION_TURN_FINISHED:
{"with_follow_on_turn": false}

正常に認識されていますね!
なお、スピーカーから相変わらず喋ってくれない模様。ぐぬぬ・・・
→どうやら音自体は出ているけど、ものすごく音量が低くて聞き取れないレベルだった模様。
 う〜む、ソースを弄るしかないということか?
 弄るとしたら↓のvolume_percentageを変更・・・かな?
 https://github.com/googlesamples/assistant-sdk-python/blob/master/google-assistant-sdk/googlesamples/assistant/grpc/audio_helpers.py
→と思ってたけど、OKグーグルしたあとに「音量を100%にして」というだけで音量上がりましたとさ・・・

8.ウェイクアップワード(ホットワード)で音を鳴らす[2019/5/9追記]

デフォルトのままでは「OKグーグル」と呼んだだけでは反応しているのかどうかがわからないため、受付後に音を鳴らします。
参考:
amikodomolabo.org


クライアントアプリのソースは以下のものが該当する。
/home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/library/hotword.py

これをエディタで開いて「ON_CONVERSATION_TURN_STARTED」で検索します。

$ vi /home/pi/env/lib/python3.5/site-packages/googlesamples/assistant/library/hotword.py
/ON_CONVERSATION_TURN_STARTED


イベント発生時、つまり「OKグーグル」と呼びかけたときの動作としてはprint出力をしているだけのようなので、ここで音を鳴らすようにすればいい模様。

音はwavファイルであれば何でもいいけど、適当なディレクトリに配置し、それを指定。
私はAlexa入れてたときに使ってた音をそのまま流用します。

if event.type == EventType.ON_CONVERSATION_TURN_STARTED:
print()

if event.type == EventType.ON_CONVERSATION_TURN_STARTED:
print()
subprocess.call("aplay /home/pi/env/dong.wav", shell=True) ←追加

ここでは、pythonのsubprocessを使って、aplayコマンドを実行します。
そのため、subprocessのimportも必要。

import argparse
import json
import os.path
import pathlib2 as pathlib

import argparse
import json
import os.path
import pathlib2 as pathlib
import subprocess ←追加

9.Alexaを入れた場合と比較して

Alexaよりウェイクアップワードの検出がかなり精度がよく、ライブラリを自分で変更しなければならないとかがないので、セットアップはとても楽。
天気を聞くなどの簡単なことについてはどちらも遜色無いですが、「〇〇について教えて」系の質問はわからないと言われたり、ピカチュウとの会話はできない(アカウント次第?)ようです。

【Ubuntu14.04】【QEMU/KVM】KVMによる仮想化UbuntuへのGPUパススルーとGPGPU(CUDA)設定

仮想WindowsでのGPUパススルーとは別に、機械学習用のセッティングの仕方について書きます。
正確には前にやってたんだけど、引っ越しの際にローレベルフォーマットを該当仮想イメージが入っているHDDにかけちゃって環境が消えたんですけどね・・・。

【参考サイト】
tech.virtualtech.jp

一応、毎回書いてるけど、KVMを利用している構成は以下の通り。
マザボ:ASRock Z170 Extreme4
・メモリ:DDR4 32G
・CPU:Core i7-6700K
・グラボ:STRIX-GTX1060-DC2O6G

1.GPUパススルー設定

と言っても、↓ですでにやっているのでほぼ不要なのですが。
engetu21.hatenablog.com


ただし、上記記事の9.vender id偽装に関しては仮想マシンごとに設定が必要なので、それは対応する必要があります。
また、 11項に記載している「ディスプレイSpice」「ビデオQXL」等のグラフィック関係の設定削除は不要です。(仮想モニタを使えるようにしておきたいので)

で、仮想マシンへのUbuntu14.04へのインストールに関しては記載を端折ります。
ちなみになんでUbuntu14.04にしたかというと、自社でGPUマシンで使ってる機械学習の画像判別ライブラリ?がCSなんとか?(うろ覚え過ぎてヤバイ)というので、それを動かせるかも確認したいからですね。
※2018/12/11追記
CSLAIERでした。しかしこれCUDA7.5が推奨・・・。CUDA10じゃ動かないかもしれないなぁ
github.com
※追記終わり

GPUパススルーの設定が終わったら、グラボが仮想OS上で認識されているかを確認します。

$ lspci | grep -i nvidia
00:02.0 VGA compatible controller: NVIDIA Corporation Device 1c03 (rev a1)
00:09.0 Audio device: NVIDIA Corporation Device 10f1 (rev a1)

問題なければ、以下のコマンドでnvidiaのドライバを落とすためのapt設定を追加します。

$ sudo add-apt-repository ppa:graphics-drivers/ppa
Fresh drivers from upstream, currently shipping Nvidia.

## Current Status

Current long-lived branch release: `nvidia-410` (410.66)
Dropped support for Fermi series (https://nvidia.custhelp.com/app/answers/detail/a_id/4656)

Old long-lived branch release: `nvidia-390` (390.87)

For GF1xx GPUs use `nvidia-390` (390.87)
For G8x, G9x and GT2xx GPUs use `nvidia-340` (340.107)
For NV4x and G7x GPUs use `nvidia-304` (304.137) End-Of-Life!

Support timeframes for Unix legacy GPU releases:
https://nvidia.custhelp.com/app/answers/detail/a_id/3142

## What we're working on right now:

  • Normal driver updates
  • Help Wanted: Mesa Updates for Intel/AMD users, ping us if you want to help do this work, we're shorthanded.

## WARNINGS:

This PPA is currently in testing, you should be experienced with packaging before you dive in here:

Volunteers welcome!

### How you can help:

## Install PTS and benchmark your gear:

    sudo apt-get install phoronix-test-suite

Run the benchmark:

    phoronix-test-suite default-benchmark openarena xonotic tesseract gputest unigine-valley

and then say yes when it asks you to submit your results to openbechmarking.org. Then grab a cup of coffee, it takes a bit for the benchmarks to run. Depending on the version of Ubuntu you're using it might preferable for you to grabs PTS from upstream directly: http://www.phoronix-test-suite.com/?k=downloads

## Share your results with the community:

Post a link to your results (or any other feedback to): https://launchpad.net/~graphics-drivers-testers

Remember to rerun and resubmit the benchmarks after driver upgrades, this will allow us to gather a bunch of data on performance that we can share with everybody.

If you run into old documentation referring to other PPAs, you can help us by consolidating references to this PPA.

If someone wants to go ahead and start prototyping on `software-properties-gtk` on what the GUI should look like, please start hacking!

## Help us Help You!

We use the donation funds to get the developers hardware to test and upload these drivers, please consider donating to the "community" slider on the donation page if you're loving this PPA:

http://www.ubuntu.com/download/desktop/contribute
詳しい情報: https://launchpad.net/~graphics-drivers/+archive/ubuntu/ppa
[ENTER] を押すと続行します。ctrl-c で追加をキャンセルできます

gpg: 鍵リング「/tmp/tmpb3yd7fes/secring.gpg」ができました
gpg: 鍵リング「/tmp/tmpb3yd7fes/pubring.gpg」ができました
gpg: 鍵1118213Cをhkpからサーバkeyserver.ubuntu.comに要求
gpg: /tmp/tmpb3yd7fes/trustdb.gpg: 信用データベースができました
gpg: 鍵1118213C: 公開鍵"Launchpad PPA for Graphics Drivers Team"をインポートしました
gpg: 究極的に信用する鍵が見つかりません
gpg: 処理数の合計: 1
gpg: インポート: 1 (RSA: 1)
OK


設定が追加されたので、apt updateします。ついでにupgradeもしておく。

$ sudo apt update
$ sudo apt upgrade

ドライバを検索します。

$ apt-cache search '^nvidia-[0-9]+'
nvidia-173 - NVIDIA legacy binary driver - version 173.14.39
nvidia-173-dev - NVIDIA binary Xorg driver development files
nvidia-304-dev - NVIDIA binary Xorg driver development files
nvidia-310 - Transitional package for nvidia-310
nvidia-310-dev - Transitional package for nvidia-310-dev
nvidia-310-updates - Transitional package for nvidia-310-updates
nvidia-310-updates-dev - Transitional package for nvidia-310-updates-dev
nvidia-313-updates - Transitional package for nvidia-313-updates
nvidia-313-updates-dev - Transitional package for nvidia-313-updates-dev
nvidia-319 - Transitional package for nvidia-319
nvidia-319-dev - Transitional package for nvidia-319-dev
nvidia-319-updates - Transitional package for nvidia-319-updates
nvidia-319-updates-dev - Transitional package for nvidia-319-updates-dev
nvidia-304-updates - Transitional package for nvidia-304
nvidia-304-updates-dev - Transitional package for nvidia-304-dev
nvidia-331 - Transitional package for nvidia-331
nvidia-331-dev - Transitional package for nvidia-340-dev
nvidia-331-updates - Transitional package for nvidia-340
nvidia-331-updates-dev - Transitional package for nvidia-340-dev
nvidia-331-updates-uvm - Transitional package for nvidia-340
nvidia-331-uvm - Transitional package for nvidia-340
nvidia-340-dev - NVIDIA binary Xorg driver development files
nvidia-340-updates - Transitional package for nvidia-340
nvidia-340-updates-dev - Transitional package for nvidia-340-dev
nvidia-340-updates-uvm - Transitional package for nvidia-340-updates
nvidia-340-uvm - Transitional package for nvidia-340
nvidia-346 - Transitional package for nvidia-346
nvidia-346-dev - Transitional package for nvidia-352-dev
nvidia-346-updates - Transitional package for nvidia-346-updates
nvidia-346-updates-dev - Transitional package for nvidia-352-updates-dev
nvidia-346-updates-uvm - Transitional package for nvidia-346-updates
nvidia-346-uvm - Transitional package for nvidia-346
nvidia-352 - Transitional package for nvidia-367
nvidia-352-dev - Transitional package for nvidia-367-dev
nvidia-352-updates - Transitional package for nvidia-367
nvidia-352-updates-dev - Transitional package for nvidia-367-dev
nvidia-367 - Transitional package for nvidia-375
nvidia-367-dev - Transitional package for nvidia-375-dev
nvidia-375 - Transitional package for nvidia-384
nvidia-375-dev - Transitional package for nvidia-384-dev
nvidia-384 - NVIDIA binary driver - version 384.130
nvidia-384-dev - NVIDIA binary Xorg driver development files
nvidia-304 - NVIDIA legacy binary driver - version 304.137
nvidia-340 - NVIDIA binary driver - version 340.107
nvidia-387-dev - Transitional package for nvidia-390-dev
nvidia-387 - Transitional package for nvidia-390
nvidia-390-dev - NVIDIA binary Xorg driver development files
nvidia-390 - NVIDIA binary driver - version 390.87
nvidia-396-dev - NVIDIA binary Xorg driver development files
nvidia-396 - NVIDIA binary driver - version 396.54
nvidia-410-dev - NVIDIA binary Xorg driver development files
nvidia-410 - NVIDIA binary driver - version 410.78
nvidia-415-dev - NVIDIA binary Xorg driver development files
nvidia-415 - NVIDIA binary driver - version 415.18

よりどりみどりですが、グラボに応じたドライバをインストールしないとダメです。
具体的にはWindowsなどでグラボ使っている際に、nvidiaのHPに行って対応するドライバを自動検索で調べておいたほうが良いかと。

$ sudo apt install nvidia-390
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下の特別パッケージがインストールされます:
bbswitch-dkms dkms fakeroot lib32gcc1 libc6-i386 libcuda1-390 libfakeroot
libjansson4 libvdpau1 libxnvctrl0 mesa-vdpau-drivers nvidia-opencl-icd-390
nvidia-prime nvidia-settings ocl-icd-libopencl1 screen-resolution-extra
vdpau-driver-all
提案パッケージ:
bumblebee dpkg-dev debhelper opencl-icd libvdpau-va-gl1 nvidia-vdpau-driver
nvidia-legacy-340xx-vdpau-driver
以下のパッケージが新たにインストールされます:
bbswitch-dkms dkms fakeroot lib32gcc1 libc6-i386 libcuda1-390 libfakeroot
libjansson4 libvdpau1 libxnvctrl0 mesa-vdpau-drivers nvidia-390
nvidia-opencl-icd-390 nvidia-prime nvidia-settings ocl-icd-libopencl1
screen-resolution-extra vdpau-driver-all
アップグレード: 0 個、新規インストール: 18 個、削除: 0 個、保留: 1 個。
84.9 MB のアーカイブを取得する必要があります。
この操作後に追加で 374 MB のディスク容量が消費されます。
続行しますか? [Y/n] y

(略)

nvidia_390:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/3.13.0-163-generic/updates/dkms/

nvidia_390_modeset.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/3.13.0-163-generic/updates/dkms/

nvidia_390_drm.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/3.13.0-163-generic/updates/dkms/

nvidia_390_uvm.ko:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/3.13.0-163-generic/updates/dkms/

depmod....

DKMS: install completed.
libcuda1-390 (390.87-0ubuntu0~gpu14.04.1) を設定しています ...
nvidia-opencl-icd-390 (390.87-0ubuntu0~gpu14.04.1) を設定しています ...
bbswitch-dkms (0.7-2ubuntu1) を設定しています ...
Loading new bbswitch-0.7 DKMS files...
First Installation: checking all kernels...
Building only for 3.13.0-163-generic
Building initial module for 3.13.0-163-generic
Done.

bbswitch:
Running module version sanity check.
- Original module
- No original module exists within this kernel
- Installation
- Installing to /lib/modules/3.13.0-163-generic/updates/dkms/

depmod....

DKMS: install completed.
nvidia-prime (0.6.2.1) を設定しています ...
nvidia-prime start/running, process 28118
screen-resolution-extra (0.17.1.1~14.04.1) を設定しています ...
nvidia-settings (415.18-0ubuntu0~gpu14.04.1) を設定しています ...
vdpau-driver-all:amd64 (1.1.1-3ubuntu1~gpu14.04.1) を設定しています ...
libc-bin (2.19-0ubuntu6.14) のトリガを処理しています ...
initramfs-tools (0.103ubuntu4.11) のトリガを処理しています ...
update-initramfs: Generating /boot/initrd.img-3.13.0-163-generic
shim-signed (1.33.1~14.04.3+13-0ubuntu2) のトリガを処理しています ...
Secure Boot not enabled on this system.
ureadahead (0.100.0-16) のトリガを処理しています ...

ここで一旦再起動をしますが、この時点でGUIで操作している場合、再起動後はグラボからの画像出力になっている可能性があります。
その状態だとCUDAをインストールしても動かないので、CUIモードで起動するように設定しておきます。

$ sudo vi /etc/default/grub
GRUB_CMDLINE_LINUX_DEFAULT="quiet nosplash"

GRUB_CMDLINE_LINUX_DEFAULT="text"

GRUBの設定を適用して再起動

$ sudo update-grub
$ sudo shutdown -r now


以下のコマンドで、GPUのステータスを出力します。
これで何らか情報が表示されていないとドライバは正常に動作していない(はず)。

$ nvidia-smi -q

==============NVSMI LOG==============

Timestamp : Sun Dec 9 23:26:57 2018
Driver Version : 390.87

Attached GPUs : 1
GPU 00000000:00:02.0
Product Name : GeForce GTX 1060 6GB
Product Brand : GeForce
Display Mode : Enabled
Display Active : Enabled
Persistence Mode : Disabled
Accounting Mode : Disabled
Accounting Mode Buffer Size : 4000
Driver Model
Current : N/A
Pending : N/A
Serial Number : N/A
GPU UUID : GPU-a201dacf-842b-9036-7645-f12273ec0de5
Minor Number : 0
VBIOS Version : 86.06.45.40.13
MultiGPU Board : No
Board ID : 0x2
GPU Part Number : N/A
Inforom Version
Image Version : G001.0000.01.04
OEM Object : 1.1
ECC Object : N/A
Power Management Object : N/A
GPU Operation Mode
Current : N/A
Pending : N/A
GPU Virtualization Mode
Virtualization mode : None
PCI
Bus : 0x00
Device : 0x02
Domain : 0x0000
Device Id : 0x1C0310DE
Bus Id : 00000000:00:02.0
Sub System Id : 0x85C51043
GPU Link Info
PCIe Generation
Max : 3
Current : 1
Link Width
Max : 16x
Current : 16x
Bridge Chip
Type : N/A
Firmware : N/A
Replays since reset : 0
Tx Throughput : 1000 KB/s
Rx Throughput : 9000 KB/s
Fan Speed : 0 %
Performance State : P8
Clocks Throttle Reasons
Idle : Active
Applications Clocks Setting : Not Active
SW Power Cap : Not Active
HW Slowdown : Not Active
HW Thermal Slowdown : Not Active
HW Power Brake Slowdown : Not Active
Sync Boost : Not Active
SW Thermal Slowdown : Not Active
Display Clock Setting : Not Active
FB Memory Usage
Total : 6078 MiB
Used : 160 MiB
Free : 5918 MiB
BAR1 Memory Usage
Total : 256 MiB
Used : 5 MiB
Free : 251 MiB
Compute Mode : Default
Utilization
Gpu : 6 %
Memory : 3 %
Encoder : 0 %
Decoder : 0 %
Encoder Stats
Active Sessions : 0
Average FPS : 0
Average Latency : 0
Ecc Mode
Current : N/A
Pending : N/A
ECC Errors
Volatile
Single Bit
Device Memory : N/A
Register File : N/A
L1 Cache : N/A
L2 Cache : N/A
Texture Memory : N/A
Texture Shared : N/A
CBU : N/A
Total : N/A
Double Bit
Device Memory : N/A
Register File : N/A
L1 Cache : N/A
L2 Cache : N/A
Texture Memory : N/A
Texture Shared : N/A
CBU : N/A
Total : N/A
Aggregate
Single Bit
Device Memory : N/A
Register File : N/A
L1 Cache : N/A
L2 Cache : N/A
Texture Memory : N/A
Texture Shared : N/A
CBU : N/A
Total : N/A
Double Bit
Device Memory : N/A
Register File : N/A
L1 Cache : N/A
L2 Cache : N/A
Texture Memory : N/A
Texture Shared : N/A
CBU : N/A
Total : N/A
Retired Pages
Single Bit ECC : N/A
Double Bit ECC : N/A
Pending : N/A
Temperature
GPU Current Temp : 24 C
GPU Shutdown Temp : 102 C
GPU Slowdown Temp : 99 C
GPU Max Operating Temp : N/A
Memory Current Temp : N/A
Memory Max Operating Temp : N/A
Power Readings
Power Management : Supported
Power Draw : 10.22 W
Power Limit : 120.00 W
Default Power Limit : 120.00 W
Enforced Power Limit : 120.00 W
Min Power Limit : 60.00 W
Max Power Limit : 140.00 W
Clocks
Graphics : 139 MHz
SM : 139 MHz
Memory : 405 MHz
Video : 544 MHz
Applications Clocks
Graphics : N/A
Memory : N/A
Default Applications Clocks
Graphics : N/A
Memory : N/A
Max Clocks
Graphics : 1974 MHz
SM : 1974 MHz
Memory : 4004 MHz
Video : 1708 MHz
Max Customer Boost Clocks
Graphics : N/A
Clock Policy
Auto Boost : N/A
Auto Boost Default : N/A
Processes
Process ID : 1121
Type : G
Name : /usr/bin/X
Used GPU Memory : 115 MiB
Process ID : 1854
Type : G
Name : compiz
Used GPU Memory : 42 MiB

2.CUDAのインストール

CUDA - Wikipedia
「CUDA(Compute Unified Device Architecture:クーダ)とは、NVIDIAが開発・提供している、GPU向けの汎用並列コンピューティングプラットフォーム(並列コンピューティングアーキテクチャ)およびプログラミングモデルである。」
とのこと。

以下のサイトにアクセスして、該当するOSを選択してダウンロードを行います。
CUDA Toolkit 10.0 Download | NVIDIA Developer
f:id:engetu21:20181209233307p:plain

ダウンロードが完了したら、ファイルをUbuntu14.04に設置し(いろいろやり方はあるけど、ファイル共有で渡すか、Ubuntu14.04を一旦GUIモードにしてからCUIモードに戻してもいい。URLがわかるならwgetで落とすのが一番楽かも)、ダウンロードボタンの横に記載されたコマンドを入力してインストールを実施。

$ sudo dpkg -i cuda-repo-ubuntu1404-10-0-local-10.0.130-410.48_1.0-1_amd64.deb
以前に未選択のパッケージ cuda-repo-ubuntu1404-10-0-local-10.0.130-410.48 を選択しています。
(データベースを読み込んでいます ... 現在 197124 個のファイルとディレクトリがインストールされています。)
cuda-repo-ubuntu1404-10-0-local-10.0.130-410.48_1.0-1_amd64.deb を展開する準備をしています ...
cuda-repo-ubuntu1404-10-0-local-10.0.130-410.48 (1.0-1) を展開しています...
cuda-repo-ubuntu1404-10-0-local-10.0.130-410.48 (1.0-1) を設定しています ...

The public CUDA GPG key does not appear to be installed.
To install the key, run this command:
sudo apt-key add /var/cuda-repo-10-0-local-10.0.130-410.48/7fa2af80.pub


$ sudo apt-key add /var/cuda-repo-10-0-local-10.0.130-410.48/7fa2af80.pub
OK

$ sudo apt update
$ sudo apt install cuda
〜長いインストール〜

3.サンプルプログラム実行

サンプルプログラムのコンパイルをします。

$ export PATH=/usr/local/cuda/bin${PATH:+:${PATH}}
$ export LD_LIBRARY_PATH=/usr/local/cuda/lib64${LD_LIBRARY_PATH:+:${LD_LIBRARY_PATH}}
$ cuda-install-samples-10.0.sh ~

Copying samples to /home/engetu/NVIDIA_CUDA-10.0_Samples now...
Finished copying samples.

$ ls ~/
NVIDIA_CUDA-10.0_Samples ←これが増えてる

$ cd NVIDIA_CUDA-10.0_Samples
$ make

(略)
Finished building CUDA samples

サンプルを動かします。

$ ~/NVIDIA_CUDA-10.0_Samples/bin/x86_64/linux/release/bandwidthTest
[CUDA Bandwidth Test] - Starting...
Running on...

Device 0: GeForce GTX 1060 6GB
Quick Mode

Host to Device Bandwidth, 1 Device(s)
PINNED Memory Transfers
Transfer Size (Bytes) Bandwidth(MB/s)
33554432 11907.0

Device to Host Bandwidth, 1 Device(s)
PINNED Memory Transfers
Transfer Size (Bytes) Bandwidth(MB/s)
33554432 10979.2

Device to Device Bandwidth, 1 Device(s)
PINNED Memory Transfers
Transfer Size (Bytes) Bandwidth(MB/s)
33554432 147017.3

Result = PASS

NOTE: The CUDA Samples are not meant for performance measurements. Results may vary when GPU Boost is enabled.

無事動きました。早いのかどうかはよくわからないけど。
あとは機械学習学習をしなければいけないわけですが、数学・・・数学かぁ・・・(尻込み)

【Raspberry Pi】サーボモータで赤外線モジュールの角度を変える

※2018/12/11追記
どうもsudo servodを実行していると、aplayというか音声出力系が正常に動作しなくなる模様(再生はしているようだけど、再生時間の割に長く再生してる上に音が全く出なくなる)。
う〜む。これがservoblasterのせいなのか、サーボモータを使っただけでこうなるのか。他の方法でもサーボモータを使ってみたいところ
※追記終わり

引越したので部屋が増えたのですが、それぞれの部屋の照明がリモコン式。
3つのうち1つは手持ちでこれまで音声で赤外線操作してたけど、新たに引越し先で大家さんが設置してくれたものが2台。
こちらの2台はirMagicianで動くことは確認しました。
engetu21.hatenablog.com

なお、機種はCL6DL-5.0
www.irisohyama.co.jp
でした。

で、本題はここからで、irMagicianの設置場所を考えていますが、赤外線の到達距離も考えるとどう考えても3部屋を賄える配置がない。追加で購入(割と高い)するのもな・・・と思って色々考えたんですが、要するに赤外線の届く角度の問題なので、irMagicianの角度が変更できればいいじゃんということに気づきました。
※と言って試したものの、今のところは2部屋の対応で妥協中。

そういうわけで、電子工作もできるラズパイでサーボモータ on irMagicianを実装します。

1.サーボモータ用のプログラムをダウンロードとインストール

ラズパイでサーボモータを動かすにはいくつか方法があるらしい。
ポピュラーな方法のServoBlasterをとりあえずやってみます。

$ git clone git://github.com/richardghirst/PiBits.git
$ cd ~/PiBits/ServoBlaster/user
$ make

gcc -Wall -g -O2 -L/opt/vc/lib -I/opt/vc/include -o servod servod.c mailbox.c -lm -lbcm_host

$ sudo make install
[ "`id -u`" = "0" ] || { echo "Must be run as root"; exit 1; }
cp -f servod /usr/local/sbin
cp -f init-script /etc/init.d/servoblaster
chmod 755 /etc/init.d/servoblaster
update-rc.d servoblaster defaults 92 08
/etc/init.d/servoblaster start

インストールできていればserviceコマンドで見られる。

$ sudo service servoblaster status
● servoblaster.service - LSB: Start/stop servod.
Loaded: loaded (/etc/init.d/servoblaster; generated; vendor preset: enabled)
Active: inactive (dead)
Docs: man:systemd-sysv-generator(8)

/dev配下にservoblasterが追加されています(仮想デバイスファイルが作られる)。

$ ls /dev/servoblaster
/dev/servoblaster

参考サイトを見るとサーボモータ1台目(0番というか0号機)の制御はGPIOポート4番、2台目(1番というか1号機)は17番、といった割り振りになっているらしい。
https://ts628-nxtlego.blogspot.com/2014/11/blog-post.html


サーボモータ1台目を動かすにはGPIOポートの4番で、ラズパイの端子7番に挿せば良いとのこと。なるほど。

実行はデバイスに対してechoするだけ

$ echo 0=130 > /dev/servoblaster

echo 0=130 は、echoコマンドででサーボモータ番号0に対して130度といった感じ。
サーボモータを2つ使う場合は、1号機指定として、echo 1=130といった感じみたいですね。

動かない場合その1として、GPIOがenableになっていない可能性がある。
その場合はラズパイの設定を変更する。

$ sudo raspi-config

f:id:engetu21:20181206223630p:plain
5 Interfacing Optionsを選択

f:id:engetu21:20181206223643p:plain
P8 Remote GPIOを選択

f:id:engetu21:20181206223656p:plain
<はい>を選択

f:id:engetu21:20181206223707p:plain
enableになったので、<了解>で完了。

動かなかった場合その2としては、serviceとしてservoblasterが動いているように見えるけど、実際には動いていない(?)可能性がある。その場合は以下のようにコマンドを打つことでサーボモータが動くようになるはず。

$ sudo servod
Board model: 2
GPIO configuration: P1 (40 pins)
Using hardware: PWM
Using DMA channel: 14
Idle timeout: Disabled
Number of servos: 8
Servo cycle time: 20000us
Pulse increment step size: 10us
Minimum width value: 50 (500us)
Maximum width value: 250 (2500us)
Output levels: Normal

Using P1 pins: 7,11,12,13,15,16,18,22

Servo mapping:
0 on P1-7 GPIO-4
1 on P1-11 GPIO-17
2 on P1-12 GPIO-18
3 on P1-13 GPIO-27
4 on P1-15 GPIO-22
5 on P1-16 GPIO-23
6 on P1-18 GPIO-24
7 on P1-22 GPIO-25

20万アクセス達成してました。

このブログを自分のメモとして作って早4年(うち2年はほぼサボりだけど)、20万アクセスを達成したようです。
f:id:engetu21:20181205191505p:plain

一応見に来た人にもわかりやすいように心がけて書いてますが、
まぁたまに「だ・である」口調になってるのは、実はそちらのほうが書きやすいからですね。
Linuxというのは中々面白いOSなので、今後もいろいろ試して継続してメモしていきたい所存。

【Raspberry Pi】PulseAudioでオーディオ出力を転送

現状、ラズパイ、小型PCといくつか持ってますが、流石にその都度スピーカーを買うのもアレなので、出力を一箇所に集中するべく、PulseAudioでの音の出力転送をします。

【参考サイト】
bluewidz.blogspot.com

今回はラズパイ3(クライアント側)→ラズパイ2(サーバ側。こちらにスピーカーを装着)

1.ラズパイ2(サーバ側)のセッティング

PulseAudioが入っていない場合もあるので、この場合はインストールから始める。

$ sudo apt update
$ sudo apt install pulseaudio

セッティングファイルをコピーしてホームディレクトリ配下に配置。
ホームディレクトリにPulsaAudioディレクトリが元々ある場合は不要だけど、無い場合は作成する。

$ mkdir ~/.config/pulse
$ cp /etc/pulse/default.pa ~/.config/pulse

コピーしたセッティングファイルは以下のように設定変更する。

$ vi ~/.config/pulse/default.pa

#load-module module-native-protocol-tcp

load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1;192.168.11.0/24

コメントアウトを解除して、authから先を記述。転送対象のローカルネットワークを指定

PulseAudioを再起動。ラズパイ2を再起動してもいい。

$ pulseaudio --kill
$ pulseaudio --start

2.ラズパイ3(クライアント側)のセッティング

以下のコマンドで1.で設定したサーバのIPアドレス環境変数に登録すればいい。

$ export PULSE_SERVER=192.168.1.81

しかし、これだけだと再起動したときにもしかしたら消えるかもなので、
ちゃんと設定しておく。

$ cp /etc/pulse/client.conf ~/.config/pulse
$ vi ~/.config/pulse/client.conf

;default-server =

default-server = 192.168.11.81
コメントアウトを外して、ラズパイ2のIPアドレスを設定

あとはラズパイ3でaplayなどで再生したファイルの音がラズパイ2で流れるのを確認すればOK。