OmniAICreator/Qiita-1.07M huggingface dataset:
Unityを始める - Unityちゃんライブステージの構造理解 -

# はじめに
以前、「 [Unityを始める - Unityインストールからプロジェクト作成 -](https://qiita.com/nekoharuyuki/items/cd845d58ecbac9ea4768) 」で、Unityを触ったことがないという人でも気軽に始められるように、Unityで開発を始める場合に必要な事をまとめました。

公開されているUnityちゃんライブステージのプロジェクトを見て、Unityのプロジェクトを学んだので備忘録としてまとめました。

![maxresdefault.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229633/4123bc2c-5f5a-0c8e-d164-b210858969bc.jpeg)
**ユニティちゃんライブステージ！ -Candy Rock Star-**

* **ダウンロードURL** ： https://unity-chan.com/download/releaseNote.php?id=CandyRockStar
* **動画** ： [ユニティちゃん Candy Rock Star ライブステージ！](https://www.youtube.com/watch?v=M_GUlXJ52YA)
* **最新バージョン** ： 1.0
* **最終リリース日** ： 2014.11.05
* **カテゴリー** ： 3D, SOUND
* **形式** ： zip

![imageLicenseLogo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/229633/250a7955-bf34-1970-2905-328171ed8ba8.png)
この作品は[ユニティちゃんライセンス条項](https://unity-chan.com/contents/license_jp/)の元に提供されています

## 参考にした本
* [UnityC#ゲームプログラミング入門 2020対応](https://amzn.to/3sbR5hc)
* [実践! ユニティちゃん トゥーンシェーダー2.0 スーパー使いこなし術](https://amzn.to/2XyIqYk)

# 動作確認

1. ユニティちゃんライブステージのダウンロード
下記のページからダウンロードしてください。
https://unity-chan.com/download/releaseNote.php?id=CandyRockStar

2. ダウンロードしたプロジェクトをUnityで開く
フォルダを展開後、 unitychan-crs-master/Assets/Scenes/Main.unity を開くとライブシーンを確認する事ができます。

# 実装
Unityちゃんライブステージの構造理解するために以下の手順で一から実装してみました。

* 新しいシーンの作成   
* ステージの作成  
* ミュージックの作成  
* ユニティちゃんを配置する
* バックスクリーンの作成
* カメラワークの設定

## 参考にしたサイト
* [ユニティちゃんライブ公開！とりあえず役立ちそうな情報とか、入手方法とかまとめてる](http://tsubakit1.hateblo.jp/entry/2014/11/05/235140)
* [ユニティちゃんライブのシーン構造について軽く解説してみる](http://tsubakit1.hateblo.jp/entry/2014/11/09/235348)

# まとめ
今回のUnityのプロジェクトの改修が初回ということもあり、うまくいかないことなどの課題は多くありましたが、このサンプルを知る事で、簡単に学習して進む事が出来ます。

ライブの面白さはアーティストとの距離が近いことだけではありません。アーティストや他のファンと同じ場を共有し、一体感を高めることで盛り上がるところにあります。バーチャルアイドルのライブも、実際のライブの中継もその一体感をいかに高めるかがポイントになってくるでしょう。 Oculus Quest 2 を持っている人はぜひ試して、どの程度の一体感が得られるように出来るのか試してみてはいかでしょうか。

今後、本格的なVR向けの開発に今後取り組む予定です。
fish shellでanyenvと〇〇envを使う方法・パスを通す

fishシェルは使いやすく見やすいのですが、癖があるため一部ツールを使う際はパスを通さねばなりません。anyenvはその一つです。
今回私はphpenvをfishで使う際に詰まってしまったので、パスを通す詳細を記録しておこうと思います。
##パス用のファイルを作る
fishの中にディレクトリとパスを通す用のファイルを作って、そこにパスを書き込むという流れです。
今回はすでにanyenvとfishをインストールしている前提とします。

```:ターミナル
$cd ~/.config/fish/
```
ここに新たにディレクトリを作ります。今回は`conf.d`という名前にします。

```:ターミナル
$mkdir conf.d
```
次に、その中にパス用のファイルを作っていきます。今回はanyenvに関するパスを通すので、`anyenv.fish`という名前のファイルにします。

```:ターミナル
$vi anyenv.fish
```
そして、`anyenv.fish`にはこのような記述をしてください。

```:ターミナル
status --is-interactive; and source (anyenv init -|psub)
```
そして、これを再起動したら使えるようになっています。

```:ターミナル
exec $SHELL -l
```

これで目的のプロジェクト中でphpenvが使えるようになりました。
[Ruby] Zeitwerk::NameErrorを解決した思考プロセス


#はじめに
ローカルでAPサーバーを立ち上げた際にZeitwerk::NameErrorが発生しました。

※今の私にとっては簡単なエラーではありません。
 ご指摘ございましたら、コメントいただけると幸いです。
　

#Error Messages

[![Image from Gyazo](https://i.gyazo.com/0975c18f7fa5aaf117ca215d89706768.png)](https://gyazo.com/0975c18f7fa5aaf117ca215d89706768)
[![Image from Gyazo](https://i.gyazo.com/4f22a792649a72c4487dc3a94e6c6a4a.png)](https://gyazo.com/4f22a792649a72c4487dc3a94e6c6a4a)
[![Image from Gyazo](https://i.gyazo.com/ac3a11b0bb22ddd94785d2ab3d8343eb.png)](https://gyazo.com/ac3a11b0bb22ddd94785d2ab3d8343eb)


#解決手順
エンジニア兼youtuberの方の動画通りに実行します。

①　証拠集め
②　証拠の意味を解釈・理解
③　証拠から原因を推測


#証拠集め
サーバー立ち上げの際に発生したエラーなので、環境系のエラーなのかな？
エラーメッセージを翻訳します
[![Image from Gyazo](https://i.gyazo.com/5ce29a06b8ff048d81c21e50b907c34d.png)](https://gyazo.com/5ce29a06b8ff048d81c21e50b907c34d)
[![Image from Gyazo](https://i.gyazo.com/e2269ba6e3dc41f4dae51b8af84e789d.png)](https://gyazo.com/e2269ba6e3dc41f4dae51b8af84e789d)

定数名が間違っていること、
解決方法を４つ教えてくれていることがわかりました。
この時点で解決はできちゃいますが、②③の手順を踏んで答えに辿りつきたいですね。

#証拠の意味を解釈・理解
証拠の中でわからない、もしくは理解が浅い単語の意味をググります。


**Zeitwerk (ツァイトヴェルク) **
Rails6から導入されたされたautoloadという仕組み。
Gemとして独立しており、Railsに限らず様々なRubyプロジェクトで利用可能。

**autoload**
命名規則に則ったファイルを自動でrequireしてくれる機能

**Module （モジュール）**
機能を1つずつ分けて他のファイルから読み込めるようにした処理のまとまりのこと
役割
① 共通に利用するAPI的な関数（モジュール関数）の提供
② 継承に代わってクラスに実装を提供
③ 名前空間の提供

**定数**
アルファベット大文字 ([A-Z]) で始まる識別子

**インフレーター**　※翻訳ではインフレクターだったが多分こっちが正しい
 気体を供給して膨張させる装置
ruby インフレーターなどでほぼヒットしなかったので一旦置いておきましょう。


#証拠から原因を推測
仮説A
このファイル名が命名規則を破ってしまっている
[![Image from Gyazo](https://i.gyazo.com/91020a24c75f956701b3cd329c1ea523.png)](https://gyazo.com/91020a24c75f956701b3cd329c1ea523)

モデルファイルの命名規則を調べます
[![Image from Gyazo](https://i.gyazo.com/e78877cfeb246cad44aa62316a2d6e4f.png)](https://gyazo.com/e78877cfeb246cad44aa62316a2d6e4f)
<a href= "https://railsdoc.com/model">Railsドキュメント</a>参照

「先頭は小文字で単数系」「単語区切りは_ 」という規則を
破っていることがわかったので、ファイル名とクラス名を下記に変更してみます。
[![Image from Gyazo](https://i.gyazo.com/960f1e28579472083a19d1fd087280cb.png)](https://gyazo.com/960f1e28579472083a19d1fd087280cb)

すると
[![Image from Gyazo](https://i.gyazo.com/44b7d99b6703287b8542830a6bbca9fe.png)](https://gyazo.com/44b7d99b6703287b8542830a6bbca9fe)
サーバーが立ち上がりました！

#おわりに
今回は仮説Aの時点で解決できました。
エラーメッセージを直接ググるのは前提が違う可能性があったり、
構造的理解力向上の妨げになるのであまり良くないですね。

手順を踏んで効率よく学びます。
PHPでの「0」と「NULL」の比較について

いろんなところで言われてますがPHPでの`0`と`NULL`の比較には注意が必要です。(ハマった)

```php
$hoge = 0;
var_dump($hoge == NULL); // bool(true)
var_dump($hoge === NULL); // bool(false)
var_dump(is_null($hoge)); // bool(false)
```

is_null()、もしくは型比較までやったほうが安全という学びでした。
セレクターについて改めて勉強し直した②

#はじめに
昨日の投稿の続きです。
[セレクターについて改めて勉強し直した①](https://qiita.com/TerToEer_sho/items/ac4105f4a8289346dce6)

##ここからは逆引き方式で

###クラス名は違うんだけど、同じスタイルを適用させたい

```html:html
<div class="section">テスト</div>
<p class="content">テスト</p>
```

```css:css
.section, .content{}
```
クラス名とクラス名の間に「,」を入れる。

---

###親要素の中の子要素にスタイルを適用させたい

```html:html
<div>
  <p>テスト</p>
</div
```

```css:css
div > p {}
```
divが親で
pが子。
Pythonのダックタイピングを理解する手段

#概要
Pythonを１、２年ながめているが、ダックタイピングが頭に入っていない。
理解する手段を考えた。

余談ですが、
頭に入っていないのは、ワタシが使っている教科書のせいかも。
ちょっと、ディスった記事↓。

[良書『入門 Python3』、説明に失敗しているところN選（N=3）。](https://qiita.com/enoughspacefor/items/1d53f38be261f3b0c8ec)

#理解する手段

簡単です。2手順です。

手順１、自分がダックタイピングだとおもっている例のコードを書いてみる。

以下、ワタシが書いたコード。点数にマイナスをつけていいなら、-60（マイナス６０点）。

セールスポイント、

* 何を思ったか。。。**継承させている**。

なぜ、こんなコードを書いてしまったか。
それは、ダックタイピングは、なんの特徴もない、あたり前のものと記憶していたから。

```python
class Tori():#鳥
    def tobe(self):
        print("bata-bata")
    def nake(self):
        print("ga-ga")

class Duck(Tori):#ダック
    def nake(self):
        print("ga-ga-ga-ga-ga-ga")

class Ahiru(Tori):#アヒル
    def tobe(self):
        print("bata-bata-bata-bata-bata")

duck_1go = Duck()
duck_1go.nake()
duck_1go.tobe()

ahiru_1go = Ahiru()
ahiru_1go.nake()
ahiru_1go.tobe()

```

手順２、正解を調べる。
よくわからなかったので、wikiに正解を求めました。

https://ja.wikipedia.org/wiki/%E3%83%80%E3%83%83%E3%82%AF%E3%83%BB%E3%82%BF%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0

wikiにrubyのコード例がありました。
pythonに書き直してみました。

```python

def test(foo):
    foo.sound()
 
class Duck():
    def sound(self):
        print('quack')

class Cat():
    def sound(self):
        print('myaa')

duck_san = Duck()
cat_san = Cat()
test(duck_san)
test(cat_san)

```

wikiでのコードに対する補足説明は、以下の1行です。

**2つのクラスに継承の関係が無いことに注目して欲しい。**

#まとめ
教科書を読むだけでは、頭に入りませんね。
コメントなどあれば、お願いします。

本来、このダックタイピングが成立している背景とか作用に意味があるのでしょうが、そのあたりは、また、理解が深まってから。。。
Google reCAPTCHAをフォームに設置する

![スクリーンショット 2021-01-13 23.33.45.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585443/f6a79242-8a83-f079-214a-4069026d2403.jpeg)

これを実装したくて、調べて、テストしてました。
忘れそうなので、備忘録も兼ねて記事にします。

# reCAPTCHAのAPIキーを取得する
### 1) reCAPTCHAにログイン
[reCAPTCHAのサイト](https://www.google.com/recaptcha/admin/create)にアクセスして、Googleアカウントでログイン。

### 2) サイトの登録

各種設定を行い、[作成]をクリックします。
![reCAPTCHA-register.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585443/dff3ae4a-5e07-345f-6bf9-8e9e00489edc.jpeg)

|項目|設定内容|
|:--|:--|
|ラベル|覚えやすい名前を入力してください|
|reCAPTCHAタイプ|使いたいものを選択してください|
|ドメイン|設置するサイトのドメインを入力してください|
|オーナー|メールアドレスが正しいか確認してください|
|reCAPTCHAに同意する|チェックをONにします|
|アラートをオーナーに送信する|ONにします|

### 3） APIキーを取得する
APIキー画面が表示されたら、それぞれコピーしておきましょう。
また、シークレットキーは絶対に流出しないようにしましょう。

![スクリーンショット 2021-01-13 22.21.35.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585443/c750e849-05a9-3112-d477-784626a59edf.jpeg)

[管理画面](https://www.google.com/recaptcha/admin/)>[設定]アイコン>[reCAPTCHAのキー]で後から確認することも可能です。

# HTMLに設置する

設置したい箇所に`<div class="g-recaptcha" data-sitekey="site key"></div>`を入力します。
`site key`にはAPIキーのサイトキーに上書きしてください。

```html:contact.html
<form action="sample.php" method="post">
    <!-- 省略 -->
    <div class="g-recaptcha" data-sitekey="site key"></div>
    <input name="submit_buton" type="submit" id="submit_button" value="送信" class="fas">
</form>
```
設置はこれで完了です。

# PHPで動作を記述する
サーバー側で、reCAPTCHAのチェックがONになっているか判定するコードを書く必要があります。

今回は、formを実行したときに呼び出すphpファイルの中に、以下のコードを追記してみました。
`secret=secretKey`の`secretKey`部分を、取得したシークレットキーに上書きしてください。

```php:sample.php
<?php
$captcha;
if (isset($_POST['g-recaptcha-response'])) {
   $captcha = $_POST['g-recaptcha-response'];
}
if (!$captcha) {
   $alert = "<script type='text/javascript'>alert('reCAPTCHA にチェックを入れて下さい。');</script>";
   echo $alert;
   echo "<script type='text/javascript'>history.go(-1);</script>";
   exit;
}
$response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=secretKey&response=" . $captcha . "&remoteip=" . $_SERVER['REMOTE_ADDR']);

// reCAPTCHAが成功した場合の処理を以降に記述
// (例: お問い合わせ送信処理、投稿処理 等)

?>
```

チェックがONになっていない場合、
`alert('reCAPTCHA にチェックを入れて下さい。');";`でブラウザの通知を使ってチェックを促し、`history.go(-1);`で自動で前のページに戻す。という処理にしています。

また、JavaScriptを使うため、`$alert = "<script type='text/javascript'>~~~</script>";`と記述して、タグの中にJavaScriptコードを記述しています。

# 実行
チェックがOFFのままフォームを送信すると、通知ウィンドウが正しく表示されました。
![スクリーンショット 2021-01-13 23.23.59.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/585443/3e86b39b-a42c-62ca-518b-3aa8b803612a.jpeg)

また、チェックがONのときは正常に送信されることを確認しました。
ターミナルからCloudWatch logsをTailする方法

# はじめに
めちゃめちゃ便利なツールを教えていただいたので、共有したいと思います。

検証用にECSのコンテナから吐き出されたログをCloudWatch logsに出力し確認することがあると思います。
その時、CloudWatch logsにStream出力されたログを、itermなどのターミナルから確認したいという方におすすめのツールを紹介します。

# AWSlogs
[awslogs](https://github.com/jorgebastida/awslogs)というツールを使用することで、この願いが叶います。

## インストール
* pipで入れたい人

```
pip install awslogs
```

* brewで入れたい人

```
brew install awslogs
```

## awslogsのサブコマンド

|サブコマンド  |説明  |
|---|---|
|groups  |CloudWatch Logsのロググループ名を表示  |
|streams  |CloudWatch Logsのストリーム名を表示  |
|get  |CloudWatch Logsのストリームに発生したイベントを表示  |

## オプション
* **-w オプション**
このオプションは、ログを表示し続けます。

* **-G オプション**
ロググループ名を省略して表示させます。

* **-S オプション**
ストリーム名を省略して表示させます。

* **--timestamp オプション**
ストリームにイベントが発生した時間を表示します。

* **-s オプション**
ストリームにイベントが発生した時間以降のログを表示させます。


# 上記を踏まえ、tailする時のコマンドはこれ
**awslogs get [log_group_name] -w -s 10m -G -S --timestamp**
意味は、10分前以降の指定したロググループのイベントをtailし、ストリーム名、ロググループ名を省略し、ストリームにイベントが発生した時間は表示するという意味です。

```
awslogs get ??? -w -s 10m -G -S --timestamp
```
React setStateでstyle切り替え

全体

```react:App.js
import React, {useState} from 'react';
import logo from './logo.svg';
import './App.css';

function App() {
  return (
    <div className="App">
      <header className="App-header">
        <img src={logo} className="App-logo" alt="logo" />
        <p>
          Edit <code>src/App.js</code> and save to reload.
        </p>
        <a
          className="App-link"
          href="https://reactjs.org"
          target="_blank"
          rel="noopener noreferrer"
        >
          Learn React
        </a>
      </header>
      <Func2/>
    </div>
  );
}

const Func2 = () => {
  const [bool,setBool] = useState(false);
  const status1 = {
    color:'blue'
  }

  const status2 = {
    color:'green'
  }

  return (
    <div>
      <h1 style={bool ? status1 : status2}>Hello</h1>
      <button onClick={()=> setBool(!bool)}>button</button>
    </div>
  );
}

export default App;
```

つくったやつ

```react
const Func2 = () => {
  const [bool,setBool] = useState(false);
  const status1 = {
    color:'blue'
  }

  const status2 = {
    color:'green'
  }

  return (
    <div>
      <h1 style={bool ? status1 : status2}>Hello</h1>
      <button onClick={()=> setBool(!bool)}>button</button>
    </div>
  );
```

ステート変数boolが変更されると再レンダリングされる 
ボタンを押すとboolが変更されて色が変わる
ラズパイでPythonから米国株価をWebAPIで取得

以前、Postmanを使って米国株価を取得してみましたが、アプリ作成に転用するため今度はラズパイからPythonを使っての取得を試みました。

PostmanでRapid APIを使って米国株価を取得する
https://qiita.com/ShinPun/items/cc9a124e3bc64b4d3893

#Pythonコード
apikeyの取得方法は上の記事をご参照ください。

```python
import requests

url = "https://www.alphavantage.co/query"

querystring = {"interval":"5min","function":"TIME_SERIES_INTRADAY","symbol":"MSFT","datatype":"json","output_size":"compact","apikey":"XXXXXXYYYYYYYZZZZZZZ"}

response = requests.request("GET", url,params=querystring)

print(response.text)

```

#取得結果

Python3.7.3の実行時の画面。
5分毎の株価が取得できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/696523/7cf6d315-92db-28b4-32e4-71d95ceff82f.png)
Next.jsの開発サーバーが立ち上がらなかったとき

初めにnextjs-blogディレクトリで
npm run dev　を実行すると、

> learn-starter@0.1.0 dev /Users/hirosawamasayuki/Desktop/nextjs-blog
> next dev
sh: next: command not found
npm ERR! code ELIFECYCLE
・
・
・
・

とエラーがでた。

解決法：npm upgrade
大量のパッケージが追加され、npm run devも可能になった。
Grav + Nginx + php-fpm環境の構築手順

## 前提

- Ubuntu
- PHP7.4
- Composerをインストール済み
- nginxの起動ユーザはwww-data
- rootユーザ実行

## php-fpmのインストールと設定

```bash:インストール
apt-get update
apt-get install php7.4-fpm 
```

以下の設定を書き込む。

```conf:/etc/php/7.4/fpm/pool.d/www.conf
user = www-data
group = www-data
listen = /run/php/php7.4-fpm.sock
```

その後再起動

```bash:自動起動と再起動
systemctl enable php7.4-fpm.service
systemctl start php7.4-fpm.service
```


## nginxのインストールと設定

```bash:インストール
apt-get update
apt-get install php7.4-fpm 
```

設定ファイルを修正

```conf:/etc/nginx/nginx.conf
user www-data;
worker_processes auto;
worker_rlimit_nofile 8192; # should be bigger than worker_connections
pid /run/nginx.pid;

events {
    worker_connections  1024;
    use epoll;
    multi_accept on;
}

http {
  include mime.types;
  default_type application/octet-stream;
  server {
    listen 80;

    root /var/www/grav;
    index index.php index.html index.htm;

    server_name libproc.com;

    location / {
      try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ [^/]\.php(/|$) {
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      if (!-f $document_root$fastcgi_script_name) {
        return 404;
      }
      fastcgi_pass  unix:/run/php/php7.4-fpm.sock;
      fastcgi_split_path_info ^(.+\.php)(/.+)$;
      fastcgi_index index.php;
      include fastcgi_params;
      fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
      fastcgi_param PATH_INFO $fastcgi_path_info;
      fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
    }
  }
}
```

```bash:自動起動と再起動
systemctl enable nginx.service
systemctl start nginx.service
```

## Gravのインストール

**composer**でインストールを実行

```
composer create-project getgrav/grav /var/www/grav
```

これで最低限のGrav導入が完了。

### Tips

- [オススメのnginx.confについて](https://learn.getgrav.org/16/webservers-hosting/servers/nginx#example-nginx-conf)
- [SSL対応](https://learn.getgrav.org/16/webservers-hosting/servers/nginx#using-ssl-with-an-existing-certificate)※ 後でやる




あと最後になりますが、よく考えたらGravで作った環境に書けば良かったと気づきました笑
無知から学ぶFIWARE #1 ～ FIWAREってなんぞや？

インターン先の会社さんからFIWAREなるものがあるので
いじってみてチュートリアルっぽいものを書いてみてくれという
ミッションを与えられたwaarrkです．どうも．

# まず謝罪
正直まだよくわかってません．めっちゃ間違ってると思います．
これからぽちぽちと進めていって，間違ってたら直します
間違ってたら教えてください．

# 調べる前のなんとなくのイメージ
なんかIoT関連のデータ形式？なのかクラウドサービス？なのか
バスでいうGTFSみたいな感じのやつ？？よね？

# 検索はたぶんすべてを解決する
と，思ったのですが専用の用語と横文字が多くて日本語のドキュメントも
英語のドキュメントも何を言ってるのかよくわかりません．
読解力がたりません．がんばりましょう．

>FIWARE is an open source initiative defining a universal set of standards for context data management which facilitate the development of Smart Solutions for different domains such as Smart Cities, Smart Industry, Smart Agrifood, and Smart Energy.
https://www.fiware.org/developers/

おん？どゆことだ？

#### FIWAREはなぜ作られたのか？
1. IoTすごいねでスマートシティが流行りそう　→ふむ
2. 使いやすくするには共通データ形式が必要　→そうやね
3. 一言にスマートシティて言っても目的さまざまだから形式もクソもない　→確かに
4. そこで基盤APIの「FIWARE」欧州でつくられたよ　→なるほどなるほど

#### じゃあFIWAREはどうやって目的さまざまのデータを管理するのか
* まずGeneric Enabler(GE)なるものが存在する

**GEは専用の機能を持ったソフトウェアのこと**で，
データ管理したり履歴を見たり解析をしたり，とにかく**いっぱい種類**があって
適切なものを使うことでデータ取得とか解析とかごにょごにょできるます（たぶん）．

* 次にNGSIというものの存在を理解する

NGSIはOpen Mobile Allianceなる団体によって標準化された次世代インターフェース
インターフェースなので，USB的なあるものにアクセスする規格的なフォーマットのことですね
NGSIには14の規格がある．そのうちFIWAREで使うのは2つ．
- **NGSI-10: データの中身を問い合わせるときに使う（オフィスの室温は？とか）**
- **NGSI-9:データの場所を問い合わせるときに使う（オフィスの室温はどのセンサ？的な）**
また，すべてのGEはNGSIに対応するよう作られているわけですね

ちなみにNGSIにはいくつかバージョンがあり
- NGSI v1: OMAが最初に作ったオリジナル
- NGSI v2: v1の改良版　仮想的なモノ→それが持つ情報→付加的情報　という三段階で階層化する
- NGSI LD: v2の双子みたいなやつ？メタを使った階層的なデータ構造ではなく，Entityから各データを参照しに行くプロパティとの関係を記述することでデータを成す（たぶん）Linkd Dataの頭文字

**じゃあ初めてFIWAREを使う人間はどのバージョンを使うとよいのか？**
まず明らかにv1 < v2なのはわかる．
v2 と LDはそもそも設計思想が違うので一概にどちらが優れているわけではなさそう
つまるところv2では付加情報（メタデータ）がないと
検索性やデータの横のつながりに優れないのでメタデータを省く代わりに
モノとその情報の関係性を記述してさらにモノとモノの関係性も記述できるようにしたと（よね？）
でもv2のほうが直感的で情報量も多いということでございますね．

きめました．とりあえず**v2**がいいと思います（逃げ腰）

>v2公式チュートリアル→ https://fiware-tutorials.readthedocs.io/en/latest/
LDチュートリアル→ https://ngsi-ld-tutorials.readthedocs.io/en/latest/

* コンテキストは情報を保持するデータモデル

FIWAREについて調べていると，いやでもcontextという単語が目に入ります．
コンテキストというのはずばり**モノの状態の情報**のこと
つまりFIWAREを使う我々が一番やりとりしたいもの
**これはNGSI規格でやりとりされるので，NGSIのフォーマット形式になっている**
具体的にはJSONのNGSIによって拡張された規格で保存されると．

私はさっきとりあえずNGSI v2を使ってみることに決めたので，コンテキストはそれにのっとり
Entity（仮想的なモノ）→ Attribute（それが持つ情報）→ MetaData（付加情報）という
3段階でJSONっぽいのが記述されるわけですね．（だんだんわかってきました）

>**ここまでのPoint**
① GEという専用の機能を持ったソフトウェア群がある
② NGSIというデータを問い合わせたりする時のインターフェースが決まっている
③ データモデルはNGSIで転送可能なJSONっぽい形式でコンテキストとして保持される

# 概要はわかったので
次回 #2 では実際にチュートリアルを動かしてコンテキスト管理をやってみたいと思います
>v2公式チュートリアル→ https://fiware-tutorials.readthedocs.io/en/latest/

次回はｺﾁﾗ→[#2 ～ GEをひとつ動かしてみる](https://qiita.com/waarrk/items/9d2431c39043c158156e)
目次はｺﾁﾗ→次回はｺﾁﾗ→[#0 ～ これは目次だよん](https://qiita.com/waarrk/items/55c64042f927d026e07d)
無知から学ぶFIWARE #0 ～ 目次だよん

# なにこれ
インターン先からFIWAREなるものがあるからいじってみてネとミッションを言い渡されたwaarrkが
がんばってFIWAREをいじってみる青春群像物語です（？）

# もくじ

[#1 ～ FIWAREってなんぞや？](https://qiita.com/waarrk/items/5f190c77fdda653e7619)
FIWAREはまだ専用の用語が多くて難しそうなイメージだったので
とりあえず概要をつかみます．
[#2 ～ GEをひとつ動かしてみる](https://qiita.com/waarrk/items/9d2431c39043c158156e)
GEの中でも最も重要なブローカーであるOrion GEをうごかしてみます
選択したボリュームの空き領域が不足しているため、アーカイブ”xcode_●●”を展開できません。


#目的
Xcodeインストールの解決策を羅列し、次回以降の早期解決を図る。

#使用環境
MacbookPro(13-inch 2017)
Big Sur(ver11.1)

#発生した問題
選択したボリュームの空き領域が不足しているため、アーカイブ”xcode_●●”を展開できません。(*)との表示があり、インストールできない。
![スクリーンショット 2021-01-13 20.59.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/665832/e7043cab-511c-ffd1-fee5-b69051dd42d9.png)

ただ、Finderを確認しても、空き容量は十分に（40GB)ありました。


##Developerページからインストール

App StoreでDLできない場合も、DeveloperページからならDLできる場合もあるらしい。
以下のURLからDeveloperページを開き、DL。
https://developer.apple.com/downloads/index.action?name=Xcode

[結果]変わらず(*)が発生。

##パージ可能な容量の開放
APFSディスクの「パージ可能な」容量は、Finderは、空き容量として、App Storeではカウントされない。そのため、Appstore上でパージ可能な容量で埋まっていてインストールできないと仮定。

※パージ可能な容量＝視聴済みのムービーとテレビ番組や、メールアプリの添付書類や、Time Machineのローカルスナップショットがある。
※[パージ可能なスペース](https://www.too.com/support/faq/mac/finder_os/24233.html
)とは
※[APFSとボリューム](https://www.storange.jp/2018/03/apfs.html
)とは

ムービ、テレビ番組、メールの添付書類に身に覚えがないので、Time Machine機能のローカルスナップショットを削除してみます。

###Time Machineをオフにする。
Apple公式によると、
>ローカルスナップショットを手動で削除したい場合は、一時的に Time Machine をオフにしてください。

>1.メニューバーの Time Machine メニュー  から Time Machine の環境設定を開きます。または、Apple メニュー  >「システム環境設定」の順に選択し、「Time Machine」をクリックします。

>2.「バックアップを自動作成」の選択を解除するか、「切／入」スイッチをクリックします (Time Machine の環境設定に表示される設定項目によって異なります)。

>3.数分経つと、ローカルスナップショットが削除されます。その後、Time Machine を再び有効にしてください。バックアップディスクは以前のまま記憶されています。

一方下記の記述もあり、Xcodeのインストールの際に、自動的にスナップショットを削除してくれるはずですが、これで解決された方もいるようです。

>スナップショットが消費している容量は、Mac では空き容量に算入されます。その上さらに、Time Machine は空き容量の多いディスクにしかローカルスナップショットを保存しないようになっているほか、スナップショットが古くなったり、ほかのことに容量が必要になったりした場合は、自動的にスナップショットを削除してくれます。

[結果]Time　Machineを利用しておらず、今回は関係なし。

##古いXcodeを削除する。
以前、入れていたXcode（消したつもりでした・・）を削除。

```terminal:terminal
cd ~/Library/Developer 
rm -rf Xcode
```

##CLT（Command Line Tools for Xcode）をDL

こちらからDL、インストール
https://developer.apple.com/download/more/

#まとめ
当環境では、古いXcodeを削除し、CLTをインストールしたところ、Xcodeをインストールできました！
pip install colourで色の操作をする

# はじめに
plotlyやpyqtgraphはカラーパレット等が無い(or 少ない？)のでmatplotlibと比べて色を指定するのに苦労します。
今回は色のグラデーションなどを簡単に作成できるモジュールがあったので紹介します。

# 環境
Mac OS
Python 3.8.5
colour 0.1.5

`pip install colour`

# 詳細
## 作成
全て赤になります。

```python
from colour import Color

Color('red')
Color(red=1)
Color('#f00')
Color('#ff0000')
Color(rgb=(1, 0, 0))  # 0~1
Color(hsl=(0, 1, 0.5))  # 0~1
Color(Color('red'))
```

## 値取得
```python
from colour import Color

c = Color('red')  # <class 'colour.Color'>
```
`c`の値を取得します。

### RGB
```python
rgb = c.get_rgb()  # (1.0, 0.0, 0.0), tuple
rgb_hex = c.get_hex()  # #f00, str
rgb_hex_long = c.get_hex_l()  # #ff0000, str
```

### HSL
```python
hsl = c.get_hsl()  # hsl色空間 (0.0, 1.0, 0.5), tuple
hue = c.get_hue()  # 色相 0.0, float
saturation = c.get_saturation()  # 彩度 1.0, float
luminance = c.get_luminance()  # 輝度 0.5, float
```
### 単色
```python
red = c.get_red()  # 1.0, float
blue = c.get_blue()  # 0.0, float
green = c.get_green()  # 0.0, float
```
## 値変更
```python
c = Color('red')  # c = red
```

`c`の値を書き換えます

```python
c.set_blue(1)  # c = magenta, set_red(), set_green()もある
c.set_saturation(0.5)  # 彩度の変更, c = #bf40bf, 0~1の間
c.set_luminance(0.2)  # 輝度の変更, c = #4c194c, 0~1の間
```

```python
# 値が上書きされる
c.set_rgb((1, 0, 0))
c.set_hsl((0, 1, 0.5))
```

## 判定
```python
Color('red') == Color('blue')
False
Color('red') == Color('red')
True
Color('red') != Color('blue')
True
Color('red') != Color('red')
False
```

## グラデーション
始めの色と終わりの色, 分割数を指定します

```python
# red - blue間
red = Color('red')
blue = Color('blue')
# 5分割 [<Color red>, <Color yellow>, <Color lime>, <Color cyan>, <Color blue>]
red_blue = list(red.range_to(blue, 5))

# black - white間
black = Color('black')
white = Color('white')
# 6分割 [<Color black>, <Color #333>, <Color #666>, <Color #999>, <Color #ccc>, <Color white>]
black_white = list(black.range_to(white, 6))

```

# 使用例
matplotlibやseabornは元々たくさん色が指定できるのであまり使わないかもしれません。
plotlyには結構使えると思います。

<img width=500 alt='スクリーンショット 2021-01-13 22.01.20.png' src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/779817/1f860eb9-253d-f44a-018a-022fd6552610.png'>


```python
from colour import Color
import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)

red = Color('red')
blue = Color('blue')
red_blue = list(red.range_to(blue, 100))

for num, color in enumerate(red_blue, 1):
    ax.plot([i for i in range(10)],
            [i * num for i in range(10)],
            c=color.get_hex_l())

plt.show()

```

# 参考
[colour · PyPI](https://pypi.org/project/colour/)
Raspberry PiにOpenCV-Pythonをインストールした

##概要
とにかく，安全にOpenCVをインストールしたいので公式の方法でインストールした．
https://docs.opencv.org/master/d2/de6/tutorial_py_setup_in_ubuntu.html
##環境

###ハード
Raspberry Pi 3 B+

###OS
```
$ cat /etc/debian_version
10.7
```


```
$ cat /etc/os-release 
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
```

##インストール


```
$ sudo apt-get install python-opencv
```

実際はこれだけで終わりだそうです．

```
>>> import cv2
>>> print(cv2.__version__)
4.5.1-dev
```

Python2ではインストール成功しました．

ただ，Python3だと，

```
>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'cv2’
>>> 
```

見つからないそうです．

パスを通そうとしてもcv2.soファイルも見つからないので，
ソースからビルドしてみようと思います．

##Building OpenCV from source

###とりあえず必要なパッケージインストール
まず，ビルドに必要な彼らをインストール．

```
sudo apt-get install cmake
sudo apt-get install gcc g++
```

Python2,3両方欲しいので

```
sudo apt-get install python-dev python-numpy
sudo apt-get install python3-dev python3-numpy
```

GTKの関連をインストール
GTKって何でしょうか．．．→GUIアプリを作るときに使うものだそうです．

```
sudo apt-get install libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev
sudo apt-get install libgtk2.0-dev
sudo apt-get install libgtk-3-dev
```

とりあえずここまででビルドまでできるみたいです．
次のやつは予備的にパッケージを更新してるだけみたいです．
###予備的にインストール(やらなくてもよい)

```
sudo apt-get install libpng-dev
sudo apt-get install libjpeg-dev
sudo apt-get install libopenexr-dev
sudo apt-get install libtiff-dev
sudo apt-get install libwebp-dev
```

###OpenCVをダウンロード
Gitからダウンロードしましょう．

```
$ sudo apt-get install git
$ git clone https://github.com/opencv/opencv.git
```
長かったですね．
ビルドのディレクトリを作ります．
名前は取りあえずbuildで

```
$ cd opencv
$ mkdir build
$ cd build
```

###インストール

続いてインストールです．

```
cmake ../
```
出力の終わりの方です．

```
--   Python 2:
--     Interpreter:                 /usr/bin/python2.7 (ver 2.7.16)
--     Libraries:                   /usr/lib/arm-linux-gnueabihf/libpython2.7.so (ver 2.7.16)
--     numpy:                       /usr/lib/python2.7/dist-packages/numpy/core/include (ver 1.16.2)
--     install path:                lib/python2.7/dist-packages/cv2/python-2.7
-- 
--   Python 3:
--     Interpreter:                 /usr/bin/python3 (ver 3.7.3)
--     Libraries:                   /usr/lib/arm-linux-gnueabihf/libpython3.7m.so (ver 3.7.3)
--     numpy:                       /usr/lib/python3/dist-packages/numpy/core/include (ver 1.16.2)
--     install path:                lib/python3.7/dist-packages/cv2/python-3.7
```

これだけでインストールを構成できるなんて便利ですよね．
何が起こってるのかはまた勉強します．

最後にビルド,インストールです．

```
$ make
# sudo make install
```
めっっっっっっちゃ時間かかりました．5時間くらい
もうしたくない！！！！！！！
###確認

```
$ python3
>>> import cv2
>>> print(cv2.__version__)
4.5.1-dev
```

できた！

##最後に
適当にやってしまったため，OpenCVを最新のdevバージョンにしてしまいました．
バージョンを変えるのにまたビルドしなかんので，**超めんどくさい**です．
####皆さんは気をつけてね．
【006_ヨセフスの問題】コマ大数学科

# 【006_ヨセフスの問題】コマ大数学科
勉強用です。
重ねて描くときにforeachを使っています。
白で塗りつぶしてもいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017176/98295384-a47c-bea2-4fad-4b679f5a73e9.png)


```latex

\begin{tikzpicture}
  \\
    \foreach \x in {0,0.1,...,1}
{
  \filldraw [rounded corners=5pt,fill=white] ({\x},{\x})rectangle ({(\x)+(1.5)},{(\x)+(2)});
}	
\node at (2,2.3)[font=\LARGE,below left]{1};
\node at (0,3)[below right]{$\maruichi$};
\draw [->,thick](2,1.5) to [out=270,in=270](0,0)node at (1,-0.4)[below]{後ろに回す};
\end{tikzpicture}
\hspace{1cm}
% 2回め
\begin{tikzpicture}
  % ==階段，放物線，
  % 線を引く
  \\
  \foreach \x in {0,0.1,...,1}
{
  \filldraw [rounded corners=5pt,fill=white] ({\x},{\x})rectangle ({(\x)+(1.5)},{(\x)+(2)});
}
\node at (2,2.3)[font=\LARGE,below left]{2};
\node at (0,3)[below right]{$\maruni$};
\draw [->,thick](2,1.5) to [out=270,in=180](2.5,-0.7)node at (2,-0.7)[left]{捨てる};
\end{tikzpicture}
\hspace{1cm}
% 3回目
\begin{tikzpicture}
  \\
    \foreach \x in {0,0.1,...,1}
{
  \filldraw [rounded corners=5pt,fill=white] ({\x},{\x})rectangle ({(\x)+(1.5)},{(\x)+(2)});
}	
\node at (2,2.3)[font=\LARGE,below left]{3};
\node at (0,3)[below right]{$\marusan$};
\draw [->,thick](2,1.5) to [out=270,in=270](0,0)node at (1,-0.4)[below]{後ろに回す};

\end{tikzpicture}
\hspace{1cm}
% 4回め
\begin{tikzpicture}
  \\
  \foreach \x in {0,0.1,...,1}
{
  \filldraw [rounded corners=5pt,fill=white] ({\x},{\x})rectangle ({(\x)+(1.5)},{(\x)+(2)});
}
\node at (2,2.3)[font=\LARGE,below left]{4};
\node at (0,3)[below right]{$\marushi$};
\draw [->,thick](2,1.5) to [out=270,in=180](2.5,-0.7)node at (2,-0.7)[left]{捨てる};
\end{tikzpicture}
```
Windows2012R2がセーフモードでも起動せず、「オプションの選択」で止まってしまう時にやったこと。

■事象
　vmwareの仮想マシン上でwindows2012R2を運用。
　配布されたKBファイルが適用されず、インストール保留の状態になっていた。
　そのため、セーフモードでもOSが起動せず、「オプションの選択」で止まってしまう。

　同じような事象
　https://social.technet.microsoft.com/Forums/ja-JP/2ea3a4d3-51f6-41d2-95ff-41c7ad06a865/window-server-2012-?forum=winserver8

■コマンドプロンプト起動方法
　オプションの選択 -> トラブルシューティング -> 詳細オプション -> コマンドプロンプト
　ドライブレターがX:\のコマンドプロンプトが起動する。
　・X:\はRAM上に展開された臨時OS。復旧先のOSはC:\とかD:\とかだと思う。
　　X:\から復旧先のドライブを操作することになる。（キーワード：WinPEのコマンドプロンプト）

■対応
　以下の処理をWinPEのコマンドプロンプトで行う。
　　1.　Systemのログを確認する。（最終シャットダウン日時を確認）
　　　　>wevtutil qe /lf <ドライブ文字:\>\Windows\System32\winevt\Logs\System.evtx /rd:true /f:text
　　
　　2.　インストールされたKBファイルを確認する。（最終シャットダウン日時と比べてみる。）
　　　　>DISM /Image:<ドライブ文字:\> /Get-Packages
　　
　　3.　インストール保留状態のKBファイルがあるので、削除した。
　　　　>DISM /Image:<ドライブ文字:\> /Remove-Package /PackageName:<パッケージID>
　　
　　4.　再起動
　　　　>wpeutil reboot
　　　

■参考

・セーフモードでも起動できないという悪夢からの脱出［その1］
https://www.atmarkit.co.jp/ait/articles/1407/08/news018.html

・wevtutil
　https://docs.microsoft.com/ja-jp/windows-server/administration/windows-commands/wevtutil
[Unity] マルチシーンについて再確認する  [1week反省会]

# これを作った時の話

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Unityroom の1week GameJam 参加してみました！<br>まだまだ完成度は上げられる状態ですが、一週間ではここまででした…<br><br>とあるESPの異界録(ラノベ感) | フリーゲーム投稿サイト <a href="https://twitter.com/hashtag/unityroom?src=hash&amp;ref_src=twsrc%5Etfw">#unityroom</a> <a href="https://t.co/HnCWQKKcVa">https://t.co/HnCWQKKcVa</a> <a href="https://twitter.com/hashtag/unity1week?src=hash&amp;ref_src=twsrc%5Etfw">#unity1week</a></p>&mdash; GoldenDuck (@Duck2Golden) <a href="https://twitter.com/Duck2Golden/status/1344325264361152512?ref_src=twsrc%5Etfw">December 30, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<P>

特に理由もなかったがシーン読み込みするならマルチシーンでしょ！みたいなノリで
ちょっとやってみたら無駄に時間をロスしたという反省会

# まずこれを読め

過去の自分にまず言いたい。

- これを読め。必要なことは大体書かれている。
    - https://madnesslabo.net/utage/?page_id=11109
        - より複雑なことをする場合はこっちも読め
            - https://docs.unity3d.com/ja/current/Manual/MultiSceneEditing.html
- 簡単にやるならこれがイケてる
    - https://qiita.com/tkyaji/items/361bd3d3d296516658f5

## そもそも全くコード書きたくない人

車輪はもう作らない！　絶対にだ！　という人は、
マルチシーンでググれば色々出てくるのでコピペすればいいと思うよ！
フルスペックを目指したシーンマネージャーみたいなものが沢山出てくるので。

# マルチシーンを設計するうえで

よくある要件を考えてみる。これらは網羅したうえで設計するのがいいだろう。

- シーン間でデータを渡したい。（シーン遷移あるある）
- シーンが閉じるまで待ちたい。（ダイアログ系追加シーンの必須要件）
- シーン遷移用アニメーションを入れたい (シングルシーンだと実質出来ないようなもの)

これプラス、公式ドキュメントに書かれている以下を忘れずに踏襲する。

```
シーンの読み込みで、マネージャーオブジェクトの役割を持つゲームオブジェクトを残したいときに
DontDestroyOnLoad を使用するのは避けてください。

代わりに、マネージャーオブジェクトを持つシーンを作成し、
ゲームの進行を管理するSceneManager.LoadScene(<path>,LoadSceneMode.Additive) と SceneManager.UnloadScene を使用します。
```

これな。
ネットにシーン遷移の仕組み公開している人でも、DontDestroyOnLoad している人はちょいちょい見る。
これをやると、**同じシーンを開きなおしたいときに詰む**。
1weekの時にこれをやって結構な時間をロスしてしまった。

こういう公式の言っている事を無視して実装すると痛い目を見るものなのです（俺のこと）
ツールは正しく使うことが大切！

### シーンが閉じるまで待ちたいとかよくあるやつ

モーダルのダイアログ（〇〇しますか？ はい/いいえ みたいなの）をシーンで作った場合や、サブシーンに必要とされることが多い。
これが仕組みとして存在していると、緊急で新しい実装を要求されてもどうにかできることが多い。
つぶしが効きやすい。（急にログインボーナス入れるとか湧いてきても大丈夫）


```
メインシーン
↓
ダイアログ
↓
メインシーンの続き
```

みたいな動き。

**メインシーンは停止しておいて、全く別の演出がしたい場合**に有効な手法だ。

ダイアログの用途だと画面の決まった位置に上書きで出したい、みたいな挙動なので、
シーン上にカメラやキャンバスを設定しておけば、どこから呼び出しても一律の表示設定にすることができる。

```C#:
var dialog = new UserDialog<T>(dialogParam);

await dialog.OpenAsync();

Debug.Log(dialog.Result); // なんか処理
```

みたいな形でちゃんと await できるように実装しておく！



# 反省まとめ

GameJamなど時間が厳しい場合は、はっきりいってシングルシーンでいいわけだが（自戒）

```タイトル``` ⇒ ```インゲーム``` * (繰り返しn回) ⇒　```リザルト``` ⇒　```タイトル```（ループ）

みたいな構造だと、殆どデメリットはない。（演出懲りたい場合は別）
シングルトンに必要なデータ保持しておいてシングルシーン読み込みでいいだろう。

実際、gamejam では、時間が無くてレベルデザイン部分は殆ど着手できなかった。

特にメモリリークをほぼ気にしなくていいのはでかい。
タイトルに戻るときなど、インゲームに関係しない場所に移動するときはシングルシーンで読み込むのは全然アリ。

(業務でもシングルシーン読み込みで一気にすっきりしてるアプリがあって驚いたことがあったが、
割とガチで綺麗になるので、脳死で安定しやすい。)


そして、

**マルチシーンにしたければ、まずマネージャーシーンを作れ**

忘れずに心に刻み込もう(-人-)

こういった汎用的な機能はテンプレにしておいた方がいい。
自分で作るか、誰かのテンプレを借りるか、あらかじめ決めておこう。
準備大切。

以上
docker-composeで立ち上げたコンテナに外から通信する

## 背景
docker-composeで立ち上げたDBコンテナに他のコンテナからconnectionを貼りたかった
その手順の備忘録

## 手順

以下のコマンドでdocker-composeで立ち上げたnetworkIDとNameを調べる

```shell
$ docker network ls
```

docker runコマンドで先程取得したID or Nameを--netで指定して実行

```shell
$ docker run -it -v "$PWD":/path/to/dir --net <network ID or Name> <image名> <command>
```

これで指定したネットワーク先のホストやエイリアスで接続できる

ホスト名がない場合は--linkでエイリアスを作成する

```shell
$ docker run -it -v "$PWD":/path/to/dir --net <network ID or Name> --link <container Name>:<host Name> <image名> <command>
```
Arduinoの使い方(IDEの設定からシリアル出力まで)


# はじめに
Arduinoの開発環境の構築から、プログラムの作成・書き込みまで
※本記事ではArduino UNOを使用

# 開発環境
* Arduino公式サイトから、使っているOSに対応したArduino IDEをダウンロードしてインストールする。
(https://www.arduino.cc/en/software)

![ArduinoIDEダウンロード.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308655/28635ea0-49fc-9469-cd8c-25c6cef8b5f5.png)

# PCとArduinoを接続
* PCとArduinoを **USB2.0 Type-B** ケーブルで接続する。
![PXL_20210113_122638116_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308655/154306ac-0255-4df1-6bc1-6185cb5eb77a.jpeg)
![PXL_20210113_122612129_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308655/2e74c237-ac62-5c0d-e515-1f4f509f4e50.jpeg)

# IDE上での設定
Arduino IDE上で、使うボードとシリアルポートの指定を行う。

1. Arduino IDEを起動する。
2. **[ツール]→[ボード]**から、使用するボードを選択する。(今回はArduino UNO)
![ボード設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308655/b1674e53-9250-421c-391f-518da40fb5b9.png)
3. **[ツール]→[シリアルポート]**から、Arduinoを認識しているポートを選択する。
![シリアルポート設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308655/4711e270-b8c4-50e9-7ec2-407b7e732994.png)

# シリアル出力でHello World
**setup()**は、起動時に1回だけ呼ばれる。
**loop()**は、**setup()**後に呼ばれ続ける。

1 . serup()内に下記ソースを追加して、シリアルポートの通信速度を指定する。

```c:
Serial.begin(9600);
```

2 . loop()内に下記ソースを追加して、1000ミリ秒ごとに文字列"Hello World"をシリアル出力する。

```c:
Serial.println("Hello World");
delay(1000);
```

* ソース全文

```c:
void setup() {
  Serial.begin(9600);
}

void loop() {
  Serial.println("Hello World");
  delay(1000);
}
```

3 . IDE上部の**"マイコンボードに書き込む"**ボタン、または**[スケッチ]→[マイコンボードに書き込む]**を選択し、プログラムのコンパイルと書き込みを行う。

![マイコンボードに書き込む.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308655/68e4d963-fa5a-1436-2d38-d130fcea2273.png)

4 . IDE右上の**"シリアルモニタ"**ボタン、または**[ツール]→[シリアルモニタ]**を選択してシリアルモニタを起動し、1000ミリ秒(1秒)ごとに"Hello World"と出力されることを確認する。
![出力結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308655/22ee5394-2ab0-9ab4-fdac-833b24142d42.png)

# おわり
Laravelで手軽にログイン認証機能を実装する

【前提条件】
Lamp環境が正常にインストール出来ている。
Node.jsのインストールが出来ている。
データ・ベースの設定が出来ている。
artisanコマンドがある程度扱える。

Node.jsがインストール出来ていない方は@seiba様の記事を参照して下さい
【引用リンク】
https://qiita.com/seibe/items/36cef7df85fe2cefa3ea

#1、バージョンを確認する
まずはLaravelのバージョンを確認しましょう、以下のコマンドを入力して下さい。

```
php artisan --version
```
Laravelのバージョンが6系か7系かを確認します。
#2、Laravel/uiをインストールする。
６系の場合は以下のコマンドでインストール

```
composer require laravel/ui:^1.0 --dev
```
7系の場合は以下のコマンドでインストール

```
composer require laravel/ui:^2.4
```
#3、認証機能を実装する
６系、７系共通で以下のコマンドを入力してログイン機能を実装する

```
php artisan ui vue --auth
```
この時点ではログイン機能は完成していません、この時点でREGISTER場面を
見てみると………フロントエンド部分が実装されていません。
![authtest.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1020834/10c1e554-33db-0232-17d3-9a8e24b2f29f.png)

#4、フロントエンド部分を実装する〜完成
npmをインストールする

```
npm install
```
npmをビルドする

```
npm run dev
```
最期に忘れずにmigrationコマンドででログイン情報を格納するテーブルを作成する。

```
php artisan migration
```
完成です
Laravelを立ち上げてみて右端のRegisterをクリックしてみる
![authtest1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1020834/60890f01-c031-36e6-3276-0f3ad42073a8.png)
すると先程は実装されていなかったフロントエンド部分の実装がなされている。
![authtest2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1020834/1acbdbd9-b2e7-27d6-6aab-e94e8825c25e.png)
  実際に登録してみる
![authtest3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1020834/dacf3f3f-2c28-f1df-2b7e-c2323b443b9a.png)

実際にログインに成功するとログイン後のページに遷移できる。
![authtest4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1020834/9f5b13de-3d5f-11e4-61a2-d503bb92be2b.png)

#番外編:どのようにデータが格納されているか
実際にパスワードが格納されているテーブルを見てみるとパスワードが暗号化されて格納されており、手軽に実装出来てかなり高度な認証機能である事がわかる。


```

|  1 | ララベルユーザー       | laravel@gmail.com | NULL |
 $2y$10$KPPRJJH0fOYl1JocEdQscu3NNl5BrJU.MpEu4AY1I2ye6F5z18Zsq | NULL           | 2021-01-13 12:40:02 | 2021-01-13 12:40:02 |
+----+--------------------+-------------------+-------------------+--------------------------------------------------------------+----------------+---------------------+---------------------+

```

参考サイト
【公式版】Laravel公式チュートリアル日本語訳
https://readouble.com/laravel/7.x/ja/authentication.html
M1 Macbook Air (Big Sur)が届いたら最初にやること。

最速組からふた足遅れてM1搭載Macbook Airを購入しました。MBP13(2013late)からの買い替えです。

以前にも[2016MBPを職場で支給された時にやることをまとめました](https://qiita.com/moomooya/items/f342bfaf4506d4df6e31)が再まとめです。

開発環境の構築はこちらで→[【随時更新】Apple Silicon (M1)での開発環境](https://qiita.com/moomooya/items/47ad55255f7b3de2add3)。

## キーボード

### [Karabiner-Elements](https://karabiner-elements.pqrs.org)導入

- `Complex modifications` > `Add rules` > `Import more rules from the Internet`
    - `International (Language Specific)` > `For Japanese （日本語環境向けの設定） (rev 5)`をインポート
    - `コマンドキーを単体で押したときに、英数・かなキーを送信する。`を有効化
- `Simple modifications`
    - `Target device`をApple Internal Keyboard / Trackpadに切り替え
    - `caps_lock`を`left_command`に設定

## トラックパッド

### `システム環境設定` > `トラックパッド`

- `タップでクリック`をチェック
- `調べる＆データ検出`を`3本指でタップ`に変更

### `システム環境設定` > `アクセシビリティ` > `ポイントコントロール`

- `トラックパッドオプション` > `ドラッグを有効にする`をチェック
- `トラックパッドオプション` > `3本指のドラッグ`に変更

## 識別名の変更

### `システム環境設定` > `共有`

- コンピュータ名を変更

## 日本語変換

### `システム環境設定` > `キーボード` > `入力ソース`

- `日本語 - ローマ字入力`
    - `ライブ変換`のチェックを外す
    - `数字を全角入力`のチェックを外す

### `システム環境設定` > `キーボード` > `ユーザ辞書`

- `スマート引用符とスマートダッシュを使用`のチェックを外す

### `システム環境設定` > `キーボード` > `ショートカット` > `入力ソース`

- `前の入力ソースを選択`のチェックを外す
- `入力メニューの次のソースを選択`のチェックを外す

Ctrl+Spaceを後でiTerm2の起動ショートカットに割り当てたいので。

## 仮想デスクトップ

### `システム環境設定` > `Mission Control`

- `最新の使用状況に基づいて操作スペースを自動的に並べ替える`のチェックを外す

## ホットコーナー

### `システム環境設定` > `Mission Control` > `ホットコーナー`

- 左下に`画面をロック`を割り当て

## Dockとメニューバー

### `システム環境設定` > `Dockとメニューバー`

- `Dockとメニューバー`
    - `サイズ`を少し小さく
    - `画面上の位置`を左に
- `サウンド`
    - `使用中のみ`を`常に`に変更
        - 音を出力しても表示されなかった。`使用中`と判定される条件がわからない
- `バッテリー`
    - `割合(％)を表示`

## Finder

### `Finder` > `環境設定` > `サイドバー`

- `最近の項目`のチェックを外す
- `(ユーザーホーム)`にチェックを入れる

### `Finder` > `環境設定` > `詳細`

- `すべてのファイルの拡張子を表示`にチェックを入れる
- `30日後にゴミ箱から項目を削除`にチェックを入れる

### `表示`

- `パスバーを表示`
- `ステータスバーを表示`

## Safari

### `表示`

- `ステータスバーを表示`
### `Safari` > `環境設定` > `一般`

- `Safariの起動時`を`最後のセッションの全ウィンドウ`に変更
- `履歴からの削除`を`1ヶ月後`に変更

### `Safari` > `環境設定` > `タブ`

- `⌘+1から⌘+9でタブを切り替える`のチェックを外す

### `Safari` > `環境設定` > `詳細`

- `WEBサイトの完全なアドレスを表示`にチェックを入れる
- `デフォルトのエンコーディング`を`Unicode (UTF-8)`に変更
- `メニューバーに"開発"メニューを表示`にチェックを入れる

## アンインストール

- iMovie
- GarageBand
- Pages
- Numbers

必要になったら入れ直す

## ドックの整理

### 使用頻度の低いアプリを削除

- Podcast
- Music
- TV
- 連絡先
- カレンダー
- FaceTime
- マップ
- メール
- メッセージ

### 順番の入れ替え
TouchDesignerでセカンドモニターを設定したまま、Window CompのOpen as separate windowをクリックすると、クラッシュして落ちてしまう

<p>TouchDesignerでセカンドモニターを設定したまま、Window CompのOpen as separate windowをクリックすると落ちてしまうので調べてみました。</p>

<p>環境は2021/01時点で最新のWindows10、ドライバーもインストール済みでTouchDesignerのバージョンも最新のバージョンを使用していました。</p>

<p>自分の使用マシンはAlienware　Area51mで、Derivativeのフォーラムを見てみると、Alienware Command Centerを削除すると症状が直るとの事で、試してみると正常に動作しました。ただ、Alienware Command Centerを削除しても出来ない方も一部いるみたいでした。</p>

<p>※Alienware Command Centerは使用出来なくなるので、こちらは自己責任でご対応ください。何か不具合が出てもこちらでは対応できません。</p>

<p>Derivativeのフォーラム<br>
<a href="https://forum.derivative.ca/t/touchdesigner-crashes-when-open-as-seperate-window-to-a-second-monitor/138178">https://forum.derivative.ca/t/touchdesigner-crashes-when-open-as-seperate-window-to-a-second-monitor/138178</a></p>

<p>公式からは、プリインストールのソフトが何らかの問題を引き起こしてしまう可能性があるので、なるべくプリインストールされているソフトウェアを除いた形でWindowsの再インストールした方がいいみたいでした。<br>
※こちらも自己責任でお願いいたします。<br>
<a href="https://twitter.com/1null1/status/1348487578631118848?s=20
">
https://twitter.com/1null1/status/1348487578631118848?s=20
</p>

<p>Twitterで上記について呟くと、結構同じような症状の方がいましたので、日本語の検索でも引っかかるよう記事にしてみました。</p>
[WPF] ウインドウメッセージハンドラをフックする

# やりたいこと

Windowsのメッセージを受け取って、その中に含まれているデータを取り出したいということがあったので、まずメッセージを受け取れるようにしたい。

イメージとしては、別の記事に書いた「[C++のダイアログベースのひな型](https://qiita.com/tera1707/items/003961a385e6bbf8a160)」の中に出てきたメッセージループ(ダイアログプロシージャ)を、C#からでも使えるようにする感じ。

ちょっと調べると、Windowsのメッセージのハンドラ(メッセージループ)をフックする、というやり方で実現できるようなので一度やってみる。

# やったこと

ざっくり手順は下記。

- フック時に行う処理を書いたメソッドを作成する
- 使うメッセージの番号を定数定義する
- 作成したメソッドを`HwndSource `を使い、フック時に実行するメソッドとして登録する

# サンプルプログラム

ここでは、例として`WM_PAINT`を取った。
`WM_PAINT`は`0x000F`なので、その値を最初に定義している。

```cs
using System;
using System.Diagnostics;
using System.Windows;
using System.Windows.Interop;

namespace WpfApp61
{
    public partial class MainWindow : Window
    {
        // メッセージの定数を定義
        private const int WM_PAINT = 0x000F;

        public MainWindow()
        {
            InitializeComponent();

            // メッセージループをフックするメソッドを登録
            //var hWnd = new WindowInteropHelper(Application.Current.MainWindow).EnsureHandle();
            var hWnd = new WindowInteropHelper(this).EnsureHandle();
            HwndSource source = HwndSource.FromHwnd(hWnd);
            source.AddHook(new HwndSourceHook(WndProc));
        }

        // メッセージループを記述したメソッド
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_PAINT)
            {
                Debug.WriteLine("WM_PAINT");
                // wparamやlparamでなにかを判定or取得する場合は下記のようにする
                if (wParam.ToInt32() == 0) { // なにかする(※WM_PAINTはwParamもlParamもなにも入ってない) }
            }
            return IntPtr.Zero;
        }
    }
}
```

これを実行すると、WM_PAINTが来たとき＝画面に描画が必要になったとき(＝ウインドウを画面の端っこにもっていって画面外に出た部分がまた画面内に戻ってきたとき等)に、WM_PAINTが来ているのを見れる。

# 参考

ダイアログベースのひな型
https://qiita.com/tera1707/items/003961a385e6bbf8a160

HwndSource クラス
https://docs.microsoft.com/ja-jp/dotnet/api/system.windows.interop.hwndsource?view=net-5.0

WPFアプリケーションでウィンドウプロシージャをフックする
https://qiita.com/tricogimmick/items/86141bc33c0e06e9d2e9
lodashのtoNumberの戻り値まとめ

`lodash`の`toNumber`の仕様がよく分からなくなったので、いろいろ実験してみました。
結論から言うと、`undefined`の時だけ注意が必要そうです。

| 引数 | 引数(コード) | 結果 |
|:-:|:-:|:-:|
|文字の'0'| '0' | 0 |
|空文字| '' | 0 |
|半角スペース| ' ' | 0 |
|全角スペース| '　' | 0 |
|null| null | 0 |
|undefined| undefined | NaN |
|数字ではない文字| 'hoge' | NaN |

### おまけ

以下で確認しました。

```js
console.log('toNumber');
let vari = '0';
console.log(vari + '->' + _.toNumber(vari));
vari = '';
console.log(vari + '->' + _.toNumber(vari));
vari = ' ';
console.log(vari + '->' + _.toNumber(vari));
vari = '　';
console.log(vari + '->' + _.toNumber(vari));
vari = null;
console.log(vari + '->' + _.toNumber(vari));
vari = undefined;
console.log(vari + '->' + _.toNumber(vari));
vari = 'hoge';
console.log(vari + '->' + _.toNumber(vari));
```
【gvm】Goのバージョン管理

# はじめに
集団開発においてバージョンを一致させる必要があり、バージョン管理はマストの作業である.
本記事はGoにおけるバージョン管理について記録を残しておく.

# Goのバージョン管理ツール 【gvm】
Goのバージョン管理ツール go version manager （以降 gvm ）を扱う
https://github.com/moovweb/gvm

# gvmの利用手順

gvm の利用手順は大きく以下の3つ

1. gvmのインストール
2. goのバージョンをインストール
3. goの特定のバージョンを利用

### 1. gvmインストール

gvmのインストールはターミナル上で以下を実行する

```
$ bash < <(curl -s -S -L https://raw.githubusercontent.com/moovweb/gvm/master/binscripts/gvm-installer)
$ source /Users/nancy/.gvm/scripts/gvm
```

インストールが正しく実行されているかを確認

```
$ gvm version
Go Version Manager v1.0.22 installed at hoge
```

### 2. goのバージョンをインストール

gvm のインストールを確認したら開発で扱う go のバージョンを取り込む.

```
gvm install go1.15.6
```

この際、下記のようなエラーが出る場合がある.

```
gvm install go1.15.6
Installing go1.15.6...
 * Compiling...
ERROR: Failed to compile. Check the logs at /Users/ko-wa/.gvm/logs/go-go1.15.6-compile.log
ERROR: Failed to use installed version
```

このエラーが出た際の対処法としてはバイナリをインストールする.

```
$ gvm install go1.15.6 -B
Installing go1.15.6 from binary source
```

参考：https://akataworks.hatenadiary.jp/entry/2016/10/18/201025

### 3. goの特定のバージョンを利用

インストールしたバージョンを再度 gvm コマンドを使って切り替える.

```
$ gvm use go1.15.6
Now using version go1.15.6
```

goのバージョンを確認する.

```
$ go version
go version go1.15.6 darwin/amd64
```

既定のバージョンになっていればオッケー！

# gvm を常に利用可能にする

gvm はターミナルを開き直すと利用できなくなるので、bash_profile（ターミナルが開かれる際に最初に実行される） に設定が必要

```
$ cat $HOME/.gvm/scripts/gvm >> ~/.bash_profile
```

書き込まれていれば、gvm が常に利用できる.

# Go のバージョンデフォルトを変更する

最後に Go のバージョンの固定したい場合にデフォルトを変更する方法を書きます.

```
$ gvm use go1.15.6 --default
Now using version go1.15.6
```

以上で Go バージョン管理、gvm の使い方になります.
Firebase AuthenticationでsignInWithPopupを使わない方が良い理由

Firebase AuthenticationでTwitter連携などをする場合、`signInWithPopup`と`signInWithRedirect`の2つのログインメソッドが存在する。

SPA開発をしている際、ページの再読み込みが行われない`signInWithPopup`の方が使い勝手が良い気がしていたのだが、いざ使ってみると思いがけない落とし穴が存在した。

どうやらiOSのSafariではデフォルトの設定でポップアップがブロックされるらしい。

これによってせっかくリリースしたアプリがログインできないなんて悲しいことが怒ってしまったりしたので、おとなしく`signInWithRedirect`を使うのが吉。
"Hello World"でみるプログラミング言語

#はじめに
プログラミングを学ぶものなら誰しも通る道、**Hello world**。今回はそんな**Hello world**を出力するためのプログラムで、５つのプログラミング言語を比較していきます。皆さんが使っていなそうな言語を選びました。**が、**あくまでも独断と偏見によって決定されています。

##1.[C](https://ja.wikipedia.org/wiki/C%E8%A8%80%E8%AA%9E)
いわずと知れた言語ですね。

```c
#include <stdio.h>
int main(void) {
    printf("Hello world\n");
}
```

##2.[Python](https://ja.wikipedia.org/wiki/Python)
簡潔に書けることが利点ですね。

```Python
print("Hello world")
```

##3.[Ruby](https://ja.wikipedia.org/wiki/Ruby)
日本生まれの言語ですね。

```Ruby
puts "Hello world"
```

##4.[FORTRAN](https://ja.wikipedia.org/wiki/FORTRAN)
最初の高水準言語として有名ですね。まだ息してたのか...

```FORTRAN
program hello
  print *, 'Hello world'
end program hello
```

##5. [PHP](https://ja.wikipedia.org/wiki/PHP_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E8%A8%80%E8%AA%9E))
HTML/CSSと一緒に使われたりしますね。

```PHP
<?php
  echo "Hello world\n";
?>
```

##終わりに
以上です。いかがでしたでしょうか？`Ruby`はやっぱり短かったですね。それが長所ですよね。`PHP`の**echo**てエコーって読むんですね。初めて知りました。若輩者ゆえ、もしかしたら間違いがあるかもしれないので、その時はコメントなんかで教えてください。
Unity キーボードの入力フィールドの削除

# キーボードの入力フィールドを削除したい

↓この赤枠部分
![IMG_2380.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006690/4dff6653-5cee-67af-57b4-e1b8536d35d9.png)

# 解決法

InputField コンポーネント > HideMobileInput にチェックする

![スクリーンショット 2021-01-13 20.53.16（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1006690/f10ad30c-fedf-8f59-8d9e-ac4a16505929.png)
「Rで四捨五入する」を参考にWolframAlphaとSymPy Liveでやってみた。

(オリジナルポスト)
https://qiita.com/snatsu/items/9a7c06cdbed3996762f2

##WolframAlphaで
round(2.5)
2
https://www.wolframalpha.com/input/?i=round%282.5%29&lang=ja

(参考)Round - Wolfram Language Documentation
https://reference.wolfram.com/language/ref/Round.html.ja
(参考)4.オトナの四捨五入＜Mathematica なんでそうなのぉ？
https://qiita.com/I_HaL/items/2970638397f17855d086
(参考)最近接丸め<wikipedia
https://ja.wikipedia.org/wiki/%E7%AB%AF%E6%95%B0%E5%87%A6%E7%90%86#:~:text=%E4%B8%B8%E3%82%81%E8%AA%A4%E5%B7%AE%E3%82%92%E5%B0%8F%E3%81%95%E3%81%8F%E6%8A%91%E3%81%88%E3%82%8B%E3%81%AB,to%20the%20nearest)%E3%80%8D%E3%81%A8%E3%81%84%E3%81%86%E3%80%82

##SymPy Liveで
https://live.sympy.org/
round(2.5)
print(round(2.5))
3
OUT PUT　CRUDについて

# <font color= "BLUE">OUT PUT CRUDについて</font>

CRUDとは
アプリケーションデータ処理に関する基本的な処理の頭文字。
アプリケーション機能は以下の処理を組み合わせて実装する。

<font color="RED">〜CRUD処理の種類〜

| アクション名 | 意味 |
|:---:|:---:|
| Create | 生成 |
| Read | 読み込み |
| Update | 更新 |
| Delete | 削除 |

:point_up:処理の頭文字をとって”CRUD”処理と呼んでいるんだね:point_up:

CRUDを実現するための[７つのアクション](https://qiita.com/takanorihagiwara/items/9a39b16d1e5af2126ac6)←この記事で
紹介しています。


---
OUT PUT END
ESP8266のサーボモータ制御ライブラリ servo の細かい挙動を知る

# ESP8266のサーボモータ制御ライブラリ servo の細かい挙動を知る

ESP8266でSG90を制御する際の、細かな挙動などについて。

## ライブラリ
servoライブラリを利用する
https://github.com/esp8266/Arduino/tree/master/libraries/Servo

PWM波形は、core_esp8266_waveform で生成している

# コンストラクタ/デストラクタ
コンストラクタは変数の初期化をしているだけ。detach()状態。
デストラクタはdetach()を行っているだけ。
双方、動的なリソース管理はしていない。

## attach()

attachは、3種類ある。

```Servo.h
uint8_t attach(int pin);
uint8_t attach(int pin, uint16_t min, uint16_t max);
uint8_t attach(int pin, uint16_t min, uint16_t max, int value);
```

min,max,valueの単位はµs、指定しない場合デフォルトが使われる。

```Servo.h
#define DEFAULT_MIN_PULSE_WIDTH      1000 // uncalibrated default, the shortest duty cycle sent to a servo
#define DEFAULT_MAX_PULSE_WIDTH      2000 // uncalibrated default, the longest duty cycle sent to a servo 
#define DEFAULT_NEUTRAL_PULSE_WIDTH  1500 // default duty cycle when servo is attached
```

デフォルトは1.0msから2.0msのパルス幅が0～180度にマップされる。
SG90は0.5msから2.4msのパルス幅なので、

```sample.cpp
    sg90.attach(PIN, 500,2400);
```
とする。

attach()時に使われる角度の初期値は、コンストラクタ、およびdetach()時にDEFAULT_NEUTRAL_PULSE_WIDTH（プログラム上1500で固定） が設定される。
SG90の場合、この値は95度くらいの値になってしまうので注意。
また、処理スピードから推察して、attach()直後にwrite()すれば大丈夫だろうと思うかもしれないが、SG90では波形更新が20ms(SG90データシート参照)ごとなので、サーボが僅かに反応する可能性がある。

初期のサーボ位置を一瞬のスキもなしに設定したい場合、attachの第３引数に初期パルス幅が指定できるので

```sample.cpp
    sg90.attach(PIN, 500,2400, map(初期角度, 0, 180, 500,2400));
```

とすれば良い。

これを含め、attach直後の挙動などを把握するには、ソースを一読した方が良い。

# write()
基本、角度指定だが、200以上の値はµsと判断され、writeMicroseconds()に渡される。 
「181度がクリップされてるから」などと油断してると、突然変な挙動になるので注意
基本、自分で0-180に正規化するのが安全。

| write(int value) | valueの取り扱い |
|:-:|:-:|
| 0未満 | 0度 |
| 0～180 | value度 |
| 181～200 | 180度 |
| 200～ | value µs / 例えば1500だと中間位置(90度) |

謎仕様だが、こういうのは、昔のソースとのコンパチのためなのだろう。


SG90では、上から見て、0は時計回りの最大角度、180は半時計回りの最大角度になる。

## detach()
attachされていたピンを常時LOWに設定後、20ms待っている。
また、内部角度をDEFAULT_NEUTRAL_PULSE_WIDTHにリセットしている。
DEFAULT_NEUTRAL_PULSE_WIDTHは、SG90の場合は前述の通り95度くらいになるので注意。

## SG90挙動
PWMパルス幅が500µsの時＝反時計回り方向に最大角度(0度)、2400µsの時＝時計回り方向に最大角度(180度)になる。１周期は20ms(50Hz)。
PWM信号が来なくなった後、一定期間(2秒程度？)は最後の角度を保持しようとするが、それを超えると角度は維持されたままモーターにトルクのかかっていない状態になる。

SG90の制御は AA51880 が使われているらしい。