2021年7月24日土曜日

転職2.0

転職2.0」読了。
きっかけは日経新聞の広告だったか、Twitterでたまたま見たか忘れたがKindleにポチられていました。著者は元ヤフーのモバイル事業の企画戦略担当者で今はLinkedin日本代表の村上臣さん。同い年か。。(汗)

感想。転職したいから手に取る本ではない。「株式会社俺」の市場価値を高めるために、日々どういう事を意識すべきかが書かれた本かな。転職はあくまでも手段。するしないにも関わらず、この意識を持って定期的にUpdateしておく事が大事だと感じた。自分自身の棚卸しですね。

 ・市場価値を高めるとは「タグ付け」をすること
 ・「タグ」を掛け合わせて、その掛け合わせの中の希少性を知ること

早速自分の職務経歴書のUpdateとタグ付けをしてみた。希少性・・・、うーん・・・。

<参考:中田Youtube大学>



2021年6月25日金曜日

無念。。システムアーキテクト

ワンチャン一発合格あるかなーと思ったけど、甘かったね。出直してきます。。

統計的には、令和3年度:合格率16.5%(元年度:15.3%、30年度:12.6%)と、直近3年を見ると合格率良かった模様。ただコロナ禍でそもそも受験者数が約3,433人と少なかったようですね(昨年5,217人)。きちんと勉強した人ばかりが集まったということか。。

秋はデータベーススペシャリスト(DB)いい加減取得します。。

高度取得5(NW、SC、AU、PM、ST、SM) 
  春コンプリートまであと1(SA)
  秋コンプリートまであと2(DB、ES)



2021年6月23日水曜日

<備忘録>Fire HD8 Plus


我が家にFire HD8 Plusが届きました(写真右)。
2週間前、3年間共に連れ添ったfire7(第7世代)文鎮化しました(電源が全く入らなくなりお亡くなり)。3年前のデジャブです、文鎮化早すぎね??

日々の日経新聞と読書をどうしようかと悩んでいた所、今回もたまたまAmazonプライムデーというイベントがあり、30日無料会員になり少し大きな8インチモデルをポチりました。本体+カバーで11,160円(実際はポイントを使ったので、9,660円)。決め手はワイヤレス充電ですかね。

Fire HD8 Plusは第10世代(2020年モデル)。7インチと比較してもそこまでゴツくない。本体容量は32GBのため十分かな(今までは8GBで結構ヤバかった)。マイクロSDで外部にも逃がせるんで、まぁ大丈夫でしょう。

さてじっくり育てますか。

fireタブレットの見分け方

2021年5月29日土曜日

<備忘録>CTU:監視カメラで動きを検知後、ドローンを出動させてみました。

 えー、プロトタイプですが、監視カメラで動きを検知したらドローンを出動させることに成功したので、簡単にメモ書いておきます。


<本当にやりたいこと>
 家の電線にムクドリがとまったら、ドローンを出動させて即座に追い払いたい。

<動機>
 およそ1月〜3月の夕方18時頃、家の電線に大量のムクドリが飛来します(以下、写真)。立つ鳥跡を濁しまくりで、周辺には大量の糞が投下され困っております。昔、東電に鳥害対策をしてもらったが効果はイマイチなようです。

<考えたこと>
 鳥が電線にとまったことを検知したら、ドローンを出動させて即座に追い払うソリューションを考えてみました。名付けて”CTU(Counter Tori Unit:トリ対策ユニット)”。

<構成イメージ>
 ①ムクドリが電線にとまる
 ②カメラで動きを検知する
 ③ドローンに指令を送る
 ④ドローンが浮上しムクドリを威嚇する
 ⑤ムクドリが逃げる

<作り方>
0)デバイスを購入
 ・RaspberryPi 4 4GB  
4)監視カメラとドローンを連動させる
4−1)ドローン起動用のシェルスクリプトを作る(event_start.sh)
・event_start.shという名前のシェルを作る

pi@raspberrypi:~ $ nano event_start.sh 


・シェルの中身はこんな雰囲気

  GNU nano 3.2                                                         event_start.sh                                                                   


#!/bin/bash


#本シェルスクリプトの置いてあるディレクトリに移動(pythonがはくlogが適切に吐き出されるように。)

cd $(dirname $0)


#トークンを記述

token="xxxご自身のtokenを記載xxx"

#LINEにメッセージを送信

curl -X POST -H "Authorization: Bearer ${token}" -F "message = ラズパイからのメッセージstart" https://notify-api.line.me/api/notify


#ドローンを動かす。result.txtに直近実行のlogを吐けるようにしとく。

python /home/pi/Tello-Python/Single_Tello_Test/tello_test.py /home/pi/Tello-Python/Single_Tello_Test/flight_test2.txt 2>&1 | tee /home/pi/result.txt


#motionを一時停止。暴走しないように。後述。

curl http://localhost:8080/0/detection/pause



・control+O(保存)、control+X(終了)でシェルを抜けた後、シェルの実行権限をつける

pi@raspberrypi:~ $ chmod +x event_start.sh 


4−2)モーションのイベント終了時のシェルスクリプトを作る(event_end.sh)
・event_end.shという名前のシェルを作る

pi@raspberrypi:~ $ nano event_end.sh 


・シェルの中身はこんな雰囲気

  GNU nano 3.2                                                          event_end.sh                                                                    


#!/bin/bash

#トークンを記述

token="xxxご自身のtokenを記載xxx"

#LINEにメッセージを送信

curl -X POST -H "Authorization: Bearer ${token}" -F "message = ラズパイからのメッセージend" https://notify-api.line.me/api/notify



・control+O(保存)、control+X(終了)でシェルを抜けた後、シェルの実行権限をつける

pi@raspberrypi:~ $ chmod +x event_end.sh 

 
4−2)motion.confに作ったシェルスクリプト組み込む
・motionの設定ファイルを開く

pi@raspberrypi:~ $ sudo nano /etc/motion/motion.conf


・control+W(検索)で、on_event と検索し設定近くに飛ぶ
・on_event_startとon_event_endの部分にシェルスクリプトを組み込む(以下、黄色)

  GNU nano 3.2                                                    /etc/motion/motion.conf                                                               


# %v = event, %q = frame number, %t = camera id number,

# %D = changed pixels, %N = noise level,

# %i and %J = width and height of motion area,

# %K and %L = X and Y coordinates of motion center

# %C = value defined by text_event

# %f = filename with full path

# %n = number indicating filetype

# Both %f and %n are only defined for on_picture_save,

# on_movie_start and on_movie_end

# Quotation marks round string are allowed.

############################################################


# Do not sound beeps when detecting motion (default: on)

# Note: Motion never beeps when running in daemon mode.

quiet on


# Command to be executed when an event starts. (default: none)

# An event starts at first motion detected after a period of no motion defined by event_gap

#; on_event_start value

on_event_start /home/pi/event_start.sh


# Command to be executed when an event ends after a period of no motion

# (default: none). The period of no motion is defined by option event_gap.

#; on_event_end value

on_event_end /home/pi/event_end.sh


# Command to be executed when a picture (.ppm|.jpg) is saved (default: none)

# To give the filename as an argument to a command append it with %f

; on_picture_save value



4−3)シェルと同じ場所にlogフォルダを作っておく
・python実行後のログが格納されます。

pi@raspberrypi:~ $ mkdir log


5)ドローンの電源を入れて数秒待って、motionを実行する
  監視カメラが動きを検知したら、ドローンが動きはじめる

pi@raspberrypi:~ $ sudo motion


6)ドローン動作終了後、実行ログを確認(動作エラー時の確認用)
・直近のログは直下のresult.txtを確認

pi@raspberrypi:~ $ cat result.txt 


id: 0

command: command

response: ok

start time: 2021-05-29 13:08:52.257217

end_time: 2021-05-29 13:08:52.315474

duration: 0.058257


id: 1

command: takeoff

response: ok

start time: 2021-05-29 13:08:52.315591

end_time: 2021-05-29 13:08:57.701102

duration: 5.385511


id: 2

command: flip b

response: ok

start time: 2021-05-29 13:08:59.703400

end_time: 2021-05-29 13:09:03.325487

duration: 3.622087


id: 3

command: flip f

response: ok

start time: 2021-05-29 13:09:05.327844

end_time: 2021-05-29 13:09:08.921326

duration: 3.593482


id: 4

command: flip l

response: ok

start time: 2021-05-29 13:09:10.923559

end_time: 2021-05-29 13:09:14.479949

duration: 3.55639


id: 5

command: flip r

response: ok

start time: 2021-05-29 13:09:16.482158

end_time: 2021-05-29 13:09:20.089971

duration: 3.607813


id: 6

command: land

response: ok

start time: 2021-05-29 13:09:22.092242

end_time: 2021-05-29 13:09:25.904518

duration: 3.812276



・logフォルダ内のファイルで過去履歴も残っている

pi@raspberrypi:~/log $ ls

'2021-05-23 16:42:56.109620.txt'  '2021-05-23 18:13:02.157302.txt'

'2021-05-23 17:30:33.422215.txt'  '2021-05-23 18:13:52.863802.txt'

'2021-05-23 17:55:20.817894.txt'  '2021-05-23 18:14:50.656453.txt'

'2021-05-23 17:58:11.359075.txt'  '2021-05-29 13:07:00.454953.txt'

'2021-05-23 17:59:02.850064.txt'  '2021-05-29 13:08:52.256574.txt'

'2021-05-23 17:59:53.879250.txt'  '2021-05-30 12:15:42.879107.txt'

'2021-05-23 18:11:40.650572.txt'


<確認・工夫したこと>
・シェルを書く前にコマンドが単体で動くことを確認した。
 当たり前かも知れんが、event_start.shの中身は一気に書けるほど分かっているわけではなく、、コマンド単体で動くかは動作確認した。試行錯誤の連続です。

・ドローン起動のトリガーに、motionのon_event_startを使った。
 最初適当にon_picture_saveにシェルスクリプトを組み込んだところドローンが暴走した(汗)。LINEに写真を送るサンプルがここだったので。on_picture_saveはカメラで写真を保存するタイミングをトリガーとする設定らしい。動きがあると連続して複数枚の写真が連続で撮影され、次々にドローンに指令が入ったため暴走したと思われる。motionの公式ページを見てみると、on_event_startはイベント(動き)がスタートしたタイミングで1度トリガーとなる。一連の動きが終わればon_event_endでクローズ(一連の動き終了)となる。また動きがあればon_event_startが実行される。一旦これを採用してみる。

・ドローンが暴走しないようにドローン起動後にmotion一時中止を入れた。
 on_event_startもどのタイミングで再実行になるかは動き次第(いつon_event_endが実行されるかは動き次第)。ドローン飛行中に再実行されると暴走の危険性があるので、苦肉の策でシェルスクリプトにmotion自体の動きを一時中止するコマンドを入れておいた。
 ドローンが無事着陸した後も連続で動くようにするには、cronで数分後にmotion再開するとか、着陸後に再開コマンド叩くとかすれば良いと思われる(未実装)。

pi@raspberrypi:~ $ curl http://localhost:8080/0/detection/pause   #motion一時停止

pi@raspberrypi:~ $ curl http://localhost:8080/0/detection/start  #motion再開


<今後>
 実はフィールドテストは未実施。ラボで動作確認しただけ。まず3月の構想から約2ヶ月経ち、ターゲットのムクドリが飛来しなくなりました…。またターゲットが現れたとしても、カメラを屋外に設置して常時鳥の動きを観察したり、監視カメラの位置・角度やmotionの設定をチューニングをしたり、お庭でドローンを電柱の高さ約10m位まで上昇させてみたりと、やることは盛り沢山。安心・安全かつ完全自動運転までは、まだまだ道のりが長そうです。動物と自然との戦いはまだまだ続く。。。

<参考>

2021年5月23日日曜日

<備忘録>プロペラガードを装着

ある程度pythonでコントロールできるようになってきたドローンですが、部屋が狭いせいか実験中に壁に激突して危険です。最初からプロペラガードは付いているものの、転倒には弱いです。ということで、ひっくり返っても安心なように全体を覆うプロペラガードを買ってみました。


<感想>
軽くて良い!計量したところ92.5gでした。このプロペラガードがつくことでホバリングが気持ち安定した気がします(フラフラと横にずれなくなった気がする)。amazonの説明にバク転はできません、って書いてあったけど普通にできました。安全面を考えても購入した方がいいですね。

<参考>

2021年5月9日日曜日

<備忘録>飛行計画通りにドローンが動くようになった。

前回ラズパイでドローンを動かせるようになりました。さらに一歩進んでDJI社公式SDKで飛行計画を立ててみようと思います。細かいやり方は、こちら参照。ほぼここのページの通りそのままやっただけ。

1. gitで公開されているSDKサンプルをダウンロード。
2. (必要に応じて)今回自宅無線LANでStationモードでTello EDUが設定されている。そのため、tello.pyの17,18行目あたりを自分用にいじる。

  GNU nano 3.2                        tello.py                                  


import socket

import threading

import time

from stats import Stats


class Tello:

    def __init__(self):

        self.local_ip = ''

        self.local_port = 8889

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # socke$

        self.socket.bind((self.local_ip, self.local_port))


        # thread for receiving cmd ack

        self.receive_thread = threading.Thread(target=self._receive_thread)

        self.receive_thread.daemon = True

        self.receive_thread.start()


#        self.tello_ip = '192.168.10.1'  #Tello EDUのデフォルトのIPはコメントアウトしておく。

        self.tello_ip = '192.168.xx.cc'  #ここをTello EDUに振られたIPアドレスにしておく。

        self.tello_port = 8889

        self.tello_adderss = (self.tello_ip, self.tello_port)

        self.log = []


        self.MAX_TIME_OUT = 15.0



3. 飛行計画用のファイルを何個か準備する。今回5個準備した。
  デフォルトでは、command.txtがあるのでこれをいじる感じ。

3-1. 離陸して5秒待って着陸する飛行計画

  GNU nano 3.2                      command.txt                                 


command

takeoff

delay 5

land



3−2. 離陸して2秒待って着陸する飛行計画

  GNU nano 3.2                      command2.txt                                


command

takeoff

delay 2

land



3−3. 離陸して左に20cm、後ろに20cm、右に20cm、前に20cm移動し着陸する飛行計画

  GNU nano 3.2                    flight_test.txt                               


command

takeoff

delay 2

left 20

delay 2

back 20

delay 2

right 20

delay 2

forward 20

delay 2

land


3−4. 離陸してバク転、前転、左回転、右回転し着陸する飛行計画

  GNU nano 3.2                    flight_test2.txt                              


command

takeoff

delay 2

flip b

delay 2

flip f

delay 2

flip l

delay 2

flip r

delay 2

land



3−5. 離陸して50cm上昇、360度時計回り旋回、50cm下降、360度反時計周り旋回し着陸する飛行計画

  GNU nano 3.2                    flight_test3.txt                    変更済み  


command

takeoff

delay 2

up 50

delay 2

cw 360

delay 2

down 50

delay 2

ccw 360

delay 2

land



4. Single_Tello_Testを動かしてみる。引数ファイルを指定しPythonを実行する。一応成功。
  実行後ログ等出力されるが詳細割愛。
  ※このSDKはPython2系のようだ。前回のサンプルはPython3系だったが。

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ python tello_test.py command.txt

(詳細割愛)

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ python tello_test.py command2.txt



pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ python tello_test.py flight_test.txt



pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ python tello_test.py flight_test2.txt



pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ python tello_test.py flight_test3.txt



<所感>
・計画通りにドローンを操作できた。
・結構本体が熱を持つ。冷却が必要か??
・狭い部屋でやってたのでたまに壁に激突し、本体が壊れるんじゃないかと超焦る。ホバリングがなぜか安定しない。その場合プログラムが最後まで実行できていないため次回実行時にソケットエラーが出るので、killしないと実行できない。

・ソケットエラー

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ python tello_test.py command2.txt

Traceback (most recent call last):

  File "tello_test.py", line 13, in <module>

    tello = Tello()

  File "/home/pi/Tello-Python/Single_Tello_Test/tello.py", line 11, in __init__

    self.socket.bind((self.local_ip, self.local_port))

  File "/usr/lib/python2.7/socket.py", line 228, in meth

    return getattr(self._sock,name)(*args)

socket.error: [Errno 98] Address already in use


・プロセスIDを調べてプロセスを強制killする(今回20201)

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ ps -fA | grep python

pi         685     1  0  5月02 ?      00:00:00 /usr/bin/python3 /usr/share/system-config-printer/applet.py

pi       20201 20030 14 16:33 pts/0    00:00:33 python tello_test.py command2.txt

pi       20259 20030  0 16:36 pts/0    00:00:00 grep --color=auto python

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ sudo lsof -i:8889

COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME

python  20201   pi    4u  IPv4 469376      0t0  UDP *:8889 

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ 

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ kill -9 20201

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ ps -fA | grep python

pi         685     1  0  5月02 ?      00:00:00 /usr/bin/python3 /usr/share/system-config-printer/applet.py

pi       20268 20030  0 16:38 pts/0    00:00:00 grep --color=auto python

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ 

pi@raspberrypi:~/Tello-Python/Single_Tello_Test $ sudo lsof -i:8889

[1]+  強制終了            python tello_test.py command2.txt



<参考>