極楽とんぼのロボット製作記

情報工学系大学院生がロボットとその周辺技術や身の回りの出来事について紹介するブログ

IRKitで指定時間に照明をつけて目覚ましにする

最近、学校へ行く道すがら梅が咲いているのを見て、「ああ、そろそろ春だなあ」などと呑気考えています。やっと寒い冬が明けて楽ができて良いのですが、ついつい寝すぎてしまって困るのがこの時期です。昔の人も「春眠暁を覚えず」とか言ったそうですね。
そこで(唐突)、今回は朝になると部屋の照明を自動でつけて、無理やり起こしてくれる”とてもありがたい”おうちハックをしようと思います。IRKitを使用して赤外線リモコンで操作できる照明を操作します。cronからIRKitのAPIのコマンドを実行して、指定時間に照明が起動できるようにします。(すでにIRKitの後継機であるNature Remoが販売されていますが、その話はまた別のところで書きたいと思います。)

使用機器

IRKit
今回、家電製品の赤外線情報を読み取って家電を操作するために使用します。後継機としてNature Remoという商品が出ています。

使用している照明
使用している照明は昼光色を5段階に調整でき、常夜灯もあります。今回は目覚めたい時間の15分前に常夜灯を付け、その後、段階的に昼光色の照明を明るくしていきます。

IRKitのセットアップや設置方法等は下記記事にまとめました。
www.g104robo.com

IRKitと通信する

IRKitと通信するためにまずはavahi-utilsを入れましょう。

$ sudo apt install avahi-utils

IPアドレスを調べる

$ avahi-browse -r _irkit._tcp
+ enp3s0 IPv4 irkit379a  _irkit._tcp local
= enp3s0 IPv4 irkit379a  _irkit._tcp local
   hostname = [iRKit.local]
   address = [IRKIT_IP]
   port = [80]
   txt = []

ローカルネットワークで操作する

IRKitが最後に受信したデータを取得(赤外線情報の記録)

リモコンをIRKitに向けて赤外線を送信しながらコマンドを実行することで、赤外線情報をJSONデータとして受信できます。

$ curl -i "http://IRKIT_IP/messages" -H "X-Requested-With: hoge"
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/3.0.0.0.g85190b1
Content-Type: text/plain
{"format":"raw","freq":38,"data":[555...666]}

{"format":"raw","freq":38,"data":[555...666]}が赤外線のデータ部分です。これをやりとりすることで照明に赤外線の信号を送信することができます。

コマンドからIRKitを操作して赤外線を送信する

先ほどのコマンドのあとに-dをつけて、得られたデータを'で囲んで実行することで赤外線データを送信することができます。

$ curl -i "http://IRKIT_IP/messages" -H "X-Requested-With: hoge" 
-d '{"format":"raw","freq":38,"data":[555...666]}'

遠隔操作する

IRKitを遠隔操作するにはdeviceidとclientkeyを取得する必要があります。これらを取得するにはまず、clienttokenを取得します。これらのidやkeyを知っているだけでIRKitを遠隔地から操作できてしまうので、これらを公開してはいけません。

clienttokenを取得する

curl -i "http://IRKIT_IP/keys" -d '' -H "X-Requested-With: hoge"
HTTP/1.0 200 OK
Access-Control-Allow-Origin: *
Server: IRKit/3.0.0.0.g85190b1
Content-Type: text/plain

{"clienttoken":"CLIENTTOKEN"}

deviceidとclientkeyを取得する

clienttokenが取得できたら、deviceidとclientkeyを取得します。

$ curl -i -d "clienttoken=CLIENTTOKEN" "https://api.getirkit.com/1/keys"
HTTP/1.1 200 OK
Server: openresty
Date: Sat, 21 Oct 2017 13:56:32 GMT
Content-Type: application/json; charset=utf-8
Content-Length: 94
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: X-Requested-With
X-Content-Type-Options: nosniff

{"deviceid":"DEVICEID","clientkey":"CLIENTKEY"}

IRKitサーバー経由で操作する

実際に遠隔地からIRKitを操作できるか確かめてみましょう。
通信環境によりますが、私の場合は20秒くらいタイムラグを経て、照明の操作が行われました。

curl -i "https://api.getirkit.com/1/messages" -d 'deviceid=DEVICEID' 
-d 'clientkey=CLIENTKEY' -d 'message={"format":"raw","freq":38,"data":[555...666]}'

cronで指定した時間に照明をつける

先ほど照明を操作したコマンドをシェルスクリプトに書いて保存しておきます。
例)

#!/bin/bash
curl -i "https://api.getirkit.com/1/messages" -d 'deviceid=DEVICEID' 
-d 'clientkey=CLIENTKEY' -d 'message={"format":"raw","freq":38,"data":[555...666]}'

今回は照明を常夜灯にする、お好みの照明(一番暗い設定をお好みとする)にする、照明を1段階明るくするの3つの赤外線データを保存し、シェルスクリプトに保存しておきます。
Linuxで一定時間ごとにコマンドを実行するにはcronが便利です。

$ crontab -e

と入力してcronの編集を行います。下記のように設定して指定時間に照明が操作されるようにします。下の例では、毎日5:45に常夜灯、5:50に一番暗い照明が点灯、その後5:53から2分毎に照明が明るくなっていきます。

45 5 * * * /home/tombo/workspace/irkit_shell/light_night_light.sh    #常夜灯点灯
50 5 * * * /home/tombo/workspace/irkit_shell/light_favorite.sh         #一番暗い照明が点灯
53-59/2 5 * * * /home/tombo/workspace/irkit_shell/light_plus1.sh    #53,55,57,59の2分毎に照明を明るくしていく

保存するとcronの実行が開始されます。保存内容を確認したい時は

$ crontab -l

として確認することができます。

これで眠い春も遅刻せずに乗り越えられますね。

参考サイト
IRKitをwindowsから操作 | 87miles.net
エアコンのオン・オフをHomeKitで操作出来るようにした - コードつれづれ
Apple HomekitとIRkitを使ったスマートホームの構築手順 - Qiita
現状これ以上を知らない、(真にプログラミングできるという意味で)プログラマブルな赤外線リモコンデバイス「IRKit」 - TsSoftLab?
IRKitを使って家に帰ったら電気がつくようにした - rdmmtd's blog
クーロン(cron)をさわってみるお - Qiita

複数のターミナルを同時に起動・分割ができるターミナルマルチプレクサ「tmux」を使ってみる


以前はTerminatorというソフトを使っていましたが、tmuxに比べてあまりにも機能が貧弱であったため、こちらに乗り換えました。

使用環境
OS: Ubuntu GNOME 16.04
tmux: 2.1

tmuxの何がうれしいか

ターミナルの分割ができる

画像のようにターミナルを分割して、1つの画面で複数のコマンドを実行します。ROSで複数のノードを立ち上げる時などに重宝します。
f:id:gokuraku104robot:20180130202713p:plain:w500

セッションの保存

せっかく分けたペイン(上で言う分割されたターミナルのこと)が起動の度にリセットされてしまうのはもったいないですよね。tmuxでは下の動画のようにウィンドウ(タブのようなもの)やペイン、セッションなどを保存してロードすることができます。
(tmux-resurrectを使用)
Prefix + Ctrl+s でセッションを保存し、Prefix + Ctrl+rでセッションのロードができます。
f:id:gokuraku104robot:20180131115058g:plain:w500

コピーモードが使える

コマンドの出力結果などをコピーする際に、マウスなどでドラッグしていませんか?tmuxならvimのヴィジュアルモードのようにコマンドの出力結果をクリップボードにコピーしたり、コマンドラインに貼り付けて実行させたりできます。エラーメッセージなどをググる時も便利です。
f:id:gokuraku104robot:20180131195920p:plain:w500

インストール

インストールするには以下のようにします。

$ sudo apt install tmux

tmuxの基本要素

tmuxを理解する上で、Session、Window、Paneの3要素を覚える必要があります。
Paneはターミナルを分割している単位
Windowは複数のPaneを束ねるタブ(のようなもの)
Sessionは複数のWindowを束ねているもの
です。
下が実際のWindowとPaneです。

f:id:gokuraku104robot:20180131202510p:plain:w500
実際のWindowとPane

SessionはPrefix + sやtmux ls等のコマンドを打つとわかります。

f:id:gokuraku104robot:20180131202813p:plain:w500
Session(Prefix + sでの表示)

基本的な操作

まずはtmuxの基本操作からです。赤字以外のPrefixを伴う操作は後で便利なキーバインドに変えるので覚える必要はありません。ここではtmuxでどんな操作ができるのかデフォルトのキーバインドでは非常に使いづらいことを感じていただければOKです。

Prefix + ? (PrefixはデフォルトではCtrl-b)
でヘルプを見ることができます。

セッションの操作

tmuxの起動

$ tmux

新しいセッションで起動
Prefix + dでセッションをデタッチして新しいセッションでtmuxを起動してみましょう。

$ tmux new-session

セッションの確認

$ tmux ls
0: 1 windows (created Thu Jan 11 15:34:44 2018) [158x41]
1: 1 windows (created Thu Jan 11 15:39:35 2018) [158x41]

セッションのデタッチ
Prefix + d

セッションのアタッチ

$ tmux attach #直前のセッションをアタッチ
$ tmux attach -t 0 #任意のセッション番号のセッションをアタッチ
$ tmux attach -t hoge #任意のセッション名のセッションをアタッチ

別のセッションへ移動
Prefix + s

セッションの削除

$ tmux kill-session -t 0 #任意のセッション番号のセッションを削除
$ tmux kill-server #すべてのセッションを削除

ウィンドウの操作

新規ウィンドウの作成
Prefix + c

ウィンドウの切り替え
Prefix + ウィンドウ番号 :ウィンドウ番号のウィンドウへ移動
Prefix + n :次のウィンドウ番号のウィンドウへ移動
Prefix + p :前のウィンドウ番号のウィンドウへ移動
Prefix + w :ウィンドウ一覧の表示と切り替え

ウィンドウの削除
Prefix + &

ペインの操作

ペインの分割
Prefix + % :垂直分割
Prefix + " :水平分割

ペイン間の移動
Prefix + o :次のペインへ移動
Prefix + q (数字の入力) :任意のペインへ移動

ペインの分割解除
Prefix + x

おすすめ設定

上で実際に手を動かしてみて、デフォルトではあまりにも使いづらいことを体感いただけたかと思います。ここからは使いやすいtmuxするべく、.tmux.confに設定を書いていきます。
とりあえずおすすめの設定で動かしたいという方はこちらを参考にしてください。

使いやすいキーバインドに設定

~/.tmux.confに以下の設定を書きます。
まずはデフォルトのPrefixを変更します。Ctrl+bはVimで連続で使用するためCtrl+tに変更します。とはいえ、Ctrl+tもCtrlP等のプラグインでタブで開く際に使用したりするので、Ctrl-tを2回押すことでCtrl+t自体も入力できるようにしておきます。

##Keybind
#Change default prefix
set-option -g prefix C-t
bind-key C-t send-prefix #Ctrl+t + Ctrl+tでCtrl+tを入力
unbind-key C-b

デフォルトのペイン分割は覚えづらいことこの上ないので直感的なバインドに変更します。

# | でペインを縦に分割する
bind | split-window -h
# - でペインを横に分割する
bind - split-window -v

ペイン移動に関してもVimと同じように移動できるように変更します。

# Vimのキーバインドでペインを移動する
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R

Prefixを押してからHJKL(Shift+h,j,k,l)でペインのサイズを変更できるようにします。 -rを指定することでPrefixを押したあと、連続でコマンドを実行することができます。

# Vimのキーバインドでペインをリサイズする
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

ウィンドウの移動はVimでのタブの移動と同じキーにしておくと便利かもしれません。

#window move
bind -r C-h select-window -t :-
bind -r C-l select-window -t :+

ここまで設定が書けたら、一度設定を反映させましょう。まずtmuxをデタッチ(Prefix+d)します。下のコマンドを実行して設定をsourceしましょう。typoがあれば何かしらのエラーが出ます。

$ tmux source ~/.tmux.conf

tmuxの設定をリロードする設定

いちいちデタッチしてから設定を読み込むのは面倒なので、tmux上で設定を再読み込みする設定を書きます。tmux.confに以下を書き込みます。

bind r source-file ~/.tmux.conf \; display "Reloaded!"

面倒ですがもう一度tmuxをデタッチして設定をsourceしましょう。これ以降は、Prefix+rで設定をsourceすることができます。

コピーに関する設定

コピー機能を使う上でクリップボードを使えるアプリをインストールします。

$ sudo apt install xsel

コピーに関する設定は以下のようにします。tmuxのバージョンが2.4未満の方はこの設定を参考にしてください。基本的にはvimと同じ挙動にしてありますが、行頭、行末への移動をH,Lに当てています。本当はSpace + h,Space + lとかにしたかったのですが、tmuxでSpaceを指定する方法がわかりませんでした。

#tmux version < 2.4
#Use vi style key bindings in copy mode
set-window-option -g mode-keys vi
#Prefix+v でコピーモード開始
bind-key v copy-mode
#pでバッファをペースト
bind-key p paste-buffer
bind-key -t vi-copy v begin-selection
bind-key -t vi-copy V select-line
#Ctrl-Vで矩形モードに切り替え
bind-key -t vi-copy C-v rectangle-toggle
#y or Enterでヤンクしてクリップボードにコピー
bind-key -t vi-copy y copy-pipe "xsel -bi"
bind-key -t vi-copy Enter copy-pipe "xsel -bi"
#ESCでコピーモードを抜ける
bind-key -t vi-copy Escape cancel
#Hで行頭
bind-key -t vi-copy H start-of-line
#Lで行末
bind-key -t vi-copy L end-of-line


tmuxのバージョンが2.4以上の方はこちらの設定を利用してください。

#tmux version >= 2.4
bind-key -T copy-mode-vi v send-keys -X begin-selection
bind-key -T copy-mode-vi V send-keys -X select-line
bind-key -T copy-mode-vi C-v send-keys -X rectangle-toggle
bind-key -T copy-mode-vi y send-keys -X copy-pipe "xsel -bi"
bind-key -T copy-mode-vi Enter send-keys -X copy-pipe "xsel -bi"
bind-key -T copy-mode-vi Escape send-keys -X cancel
bind-key -T copy-mode-vi H send-keys -X start-of-line
bind-key -T copy-mode-vi L send-keys -X end-of-line

プラグインの設定

tmuxには便利なプラグインが多数用意されています。これらをインストールすることでさらに便利なターミナル環境を構築できます。まずはtmuxのプラグインマネージャであるtpm(TmuxPluginManager)をインストールしましょう。
gitからtpmをクローンしてきます。

$git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

.tmux.confの最後に以下の設定を追加します。

# List of plugins
set -g @plugin 'tmux-plugins/tpm'

# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'

tpmの基本的な操作は以下の通りです。
プラグインのインストール: Prefix + I
プラグインのアップデート: Prefix + U
プラグインのアンインストール: Prefix + Alt + u

カラースキームの設定

tmuxプラグインをインストールする準備ができたので、さっそくカラースキームを入れてtmuxの見た目を良くしましょう。今回はsolarizedを入れます。

set -g @plugin 'seebi/tmux-colors-solarized'

設定をsourceしてから、Prefix+Iでプラグインをインストールしましょう。tmuxの色が変わったと思います。

セッションの自動保存と自動読み込み

冒頭でお見せしたセッションの自動保存と自動読み込みについて説明します。これらの機能を実現するにはtmux-resurrectとtmux-continuumを入れます。

set -g @plugin 'tmux-plugins/tmux-resurrect'    #Prefix C-sでセッション保存 C-rでセッションリロード
set -g @plugin 'tmux-plugins/tmux-continuum'
    set -g @continuum-restore 'on'              #tmuxスタート時に自動で復元
    set -g @continuum-save-interval '1'         #セッションを保存する間隔を1分にする

設定をsourceしてから、Prefix+Iでプラグインをインストールしましょう。まずtmux-resurrectの機能としてPrefix + Ctrl+sでセッションの保存、Prefix + Ctrl+rでセッションのロードができるようになっていると思います。またPCを再起動してからtmux lsをすると再起動前のセッションが残っています。ここからtmux attachで任意のセッションを開きましょう。
(本当はPC起動時にtmuxが起動して、自動でセッションを読み込むようにしたかったのですが、Ubuntuではすぐに設定できませんでした。また勉強してから書こうと思います。MACの方はすぐにできるので便利ですね)

最終的な.tmux.conf

これが上の設定をすべて盛り込んだ最終的な.tmux.confです。これを~/.tmux.confに保存してtmuxを立ち上げれば、設定がロードされます。以降はPrefix(この設定の場合Ctrl+t) + rで設定をリロードすることができます。Prefix+Iでプラグインのインストールができます。

##Keybind
#Change default prefix
set-option -g prefix C-t
bind-key C-t send-prefix
unbind-key C-b
# | でペインを縦に分割する
bind | split-window -h
# - でペインを横に分割する
bind - split-window -v
# Vimのキーバインドでペインを移動する
bind -r h select-pane -L
bind -r j select-pane -D
bind -r k select-pane -U
bind -r l select-pane -R
#window move
bind -r C-h select-window -t :-
bind -r C-l select-window -t :+
# Vimのキーバインドでペインをリサイズする
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5
#window move
bind -r C-h select-window -t :-
bind -r C-l select-window -t :+

##Copy
#Use vi style key bindings in copy mode
set-window-option -g mode-keys vi
#Prefix+v でコピーモード開始
bind-key v copy-mode
#pでバッファをペースト
bind-key p paste-buffer
bind-key -t vi-copy v begin-selection
bind-key -t vi-copy V select-line
#Ctrl-Vで矩形モードに切り替え
bind-key -t vi-copy C-v rectangle-toggle
#y or Enterでヤンクしてクリップボードにコピー
bind-key -t vi-copy y copy-pipe "xsel -bi"
bind-key -t vi-copy Enter copy-pipe "xsel -bi"
#ESCでコピーモードを抜ける
bind-key -t vi-copy Escape cancel
#Hで行頭
bind-key -t vi-copy H start-of-line
#Lで行末
bind-key -t vi-copy L end-of-line

# ウィンドウ分割後もカレントディレクトリに留まる
#if-shell "~/dotfiles/bin/tmux-version-check 1.9" '
bind c new-window -c "#{pane_current_path}"
bind | split-window -h -c "#{pane_current_path}"
bind - split-window -v -c "#{pane_current_path}"

# ウィンドウを閉じた時に番号を詰める
#if-shell "~/dotfiles/bin/tmux-version-check 1.7"
set-option -g renumber-windows on

##Color
# 256色端末を使用する
set -g default-terminal "screen-256color"

##Status bar
# ステータスバーを Utf-8 に対応
set-option -g status-utf8 on
# ステータスバーを1秒毎に描画し直す
set-option -g status-interval 1
# 左右のステータスバーの長さを決定する
set-option -g status-left-length 90
set-option -g status-right-length 90
# 最左に表示 #H(マシン名) #P(ペイン番号)
set-option -g status-left '#H:[#P]'

##Others
#enable mouse
set-option -g mouse on

#reload settings
bind r source-file ~/.tmux.conf \; display "Reloaded!"

#set history limit 10000
set-option -g history-limit 10000

# List of plugins
set -g @plugin 'tmux-plugins/tpm'
set -g @plugin 'seebi/tmux-colors-solarized'
    set -g @colors-solarized '256'
set -g @plugin 'tmux-plugins/tmux-resurrect'    #Prefix C-sでセッション保存 C-rでセッションリロード
set -g @plugin 'tmux-plugins/tmux-continuum'
    set -g @continuum-restore 'on'              #tmuxスタート時に自動で復元
    set -g @continuum-save-interval '1'         #セッションを保存する間隔を1分にする
    #set -g status-right 'Continuum status: #{continuum_status}' #continuumのステータスを表示

# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'


dotfilesの設定方法
.tmux.confもgithub等に保存してすぐに環境構築できるようにしたいですよね。dotfilesの管理方法を下の記事にまとめました。
www.g104robo.com

vimのタブ(セッション)を保存する「vim-session」

作業を開始するたびに複数のタブを開き直すのは大変ですよね。そんなあなたにvim-sessionをおすすめします。閉じた際のタブの状態(セッション)を保存して、もう1度開くときにそのセッションを読み込んで表示してくれます。


参考サイト
qiita.com

以下に、dein.tomlの設定例を示します。

" # dein.toml
[[plugins]]
repo = 'xolox/vim-session'
depends = ['xolox/vim-misc']
hook_add = '''
    " # 現在のディレクトリ直下の .vimsessions/ を取得
    let s:local_session_directory = xolox#misc#path#merge(getcwd(), '.vimsessions')
    " # 存在すれば
    if isdirectory(s:local_session_directory)
      " # session保存ディレクトリをそのディレクトリの設定
      let g:session_directory = s:local_session_directory
      " # vimを辞める時に自動保存
      let g:session_autosave = 'yes'
      " # 引数なしでvimを起動した時にsession保存ディレクトリのdefault.vimを開く
      let g:session_autoload = 'yes'
      " # 1分間に1回自動保存
      let g:session_autosave_periodic = 1
    else
      " # デフォルトの保存ディレクトリを変更する(NeoVimの場合)
      let g:session_directory = '~/.config/nvim/sessions'
      let g:session_autosave = 'yes'
      let g:session_autoload = 'yes'
      let g:session_autosave_periodic = 1
    endif
    unlet s:local_session_directory
	'''
[[plugins]]
repo = 'xolox/vim-misc'

vim-sessionはvim-miscに依存しているのでdependsを必ず書きます。

vimを起動したら以下のコマンドを入力して、セッションを保存したり、開いたりできます。
:SaveSession (default.vimにセッションを保存)
:SaveSession hoge (hoge.vimにセッションを保存)
:OpenSession (default.vimを開く)
:OpenSession hoge (hoge.vimを開く)

vimを:qaで閉じるとdefault.vimに自動的にセッションが保存されて、次に開くときにdefault.vimから開かれます。


参考サイト
vimでウィンドウやタブの状態を自動保存/復元する方法 - Qiita
GitHub - xolox/vim-session: Extended session management for Vim (:mksession on steroids)
NeoBundle から dein.vim に乗り換えたら爆速だった話 - Qiita

【ROS】The manifest (with format version 2) must not contain the following tags: run_depend

ROSで自分で作ったメッセージをコンパイルしようとした際に出たエラーです。
エラー全文
Error(s) in /home/username/catkin_ws/src/segment_point_cloud/package.xml:

  • The manifest (with format version 2) must not contain the following tags: run_depend

ROSのチュートリアルにはpackage.xmlにrun_dependを追記するように書いてありますが、バージョンが新しくなってからはexec_dependを使用するようになっています。
package.xmlの中の
hoge

hoge
に変更すれば問題なく動きます。

参考にしたROSチュートリアル
ja/ROS/Tutorials/CreatingMsgAndSrv - ROS Wiki

【C++】(.text+0x20): `main' に対する定義されていない参照です

「くそ、こんなことで! 」と数十分を無駄にした自分に対する怒りの発散と戒めを込めてエラーと対処方法を書きました。C++を学び始めた方の手助けになればと思います。
環境は
OS: Ubuntu 16.04
コンパイラ: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.5) 5.4.0 20160609

エラー全文

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: 関数 `_start' 内:
(.text+0x20): `main' に対する定義されていない参照です
collect2: error: ld returned 1 exit status
CMakeFiles/f-manager.dir/build.make:94: ターゲット 'f-manager' のレシピで失敗しました
make[2]: *** [f-manager] エラー 1
CMakeFiles/Makefile2:67: ターゲット 'CMakeFiles/f-manager.dir/all' のレシピで失敗しました
make[1]: *** [CMakeFiles/f-manager.dir/all] エラー 2
Makefile:83: ターゲット 'all' のレシピで失敗しました
make: *** [all] エラー 2

エラーを見るといかにも仰々しいことが書かれていますが、単にmain関数が無いか、nain等のtypoをしている例です。

エラー全文

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: 関数 `_start' 内:
(.text+0x20): `main' に対する定義されていない参照です
collect2: error: ld returned 1 exit status
segment_point_cloud/CMakeFiles/segment_point_cloud_node.dir/build.make:391: ターゲット '/home/username/omni_ros/devel/lib/segment_point_cloud/segment_point_cloud_node' のレシピで失敗しました
make[2]: *** [/home/username/omni_ros/devel/lib/segment_point_cloud/segment_point_cloud_node] エラー 1
CMakeFiles/Makefile2:2206: ターゲット 'segment_point_cloud/CMakeFiles/segment_point_cloud_node.dir/all' のレシピで失敗しました
make[1]: *** [segment_point_cloud/CMakeFiles/segment_point_cloud_node.dir/all] エラー 2
Makefile:138: ターゲット 'all' のレシピで失敗しました
make: *** [all] エラー 2
Invoking "make -j4 -l4" failed

ROSで同じようなことをやらかした時の例です。こちらはCMakeList.txtにtarget_link_librariesを指定し忘れた時にでました。
こんな感じでmain関数が無いのとtarget_link_librariesが無いのがコンパイラ側ではほぼ同じエラーとして出力されるので、結構分かりづらいです。
最後に最近見ていいなと思ったツイートを紹介します。


あまり深刻にならずにどんどんエラーにぶつかっていこうと思います。

新しいVim、"Neovim"を導入する

Neovim導入の仕方を説明します。

Neovimのインストール

参考サイト
github.com
Neovimをインストールする手順は以下の通りです。

$ sudo add-apt-repository ppa:neovim-ppa/stable
$ sudo apt-get update
$ sudo apt-get install neovim

インストールが終了したら

$ nvim

と打ってneovimを起動してみましょう。
f:id:gokuraku104robot:20171130152850p:plain

vimやviでnvimを起動するようにする

お好みですが、vimやviなどでneovimを起動するには以下の設定をします。

$ sudo update-alternatives --install /usr/bin/vi vi /usr/bin/nvim 60
$ sudo update-alternatives --config vi
$ sudo update-alternatives --install /usr/bin/vim vim /usr/bin/nvim 60
$ sudo update-alternatives --config vim

.vimrcの引っ越し

NeovimでもこれまでのVimの設定をほぼそのまま利用することができます。Neovimでは設定ファイルはinit.vimで、~/.config/nvim/以下に置かれます。
VimとNeovimで同じ設定をしたい場合は

ln -s ~/.vimrc ~/.config/nvim/init.vim

としてシンボリックリンクを貼ればNeovimが読み込んでくれます。
NeovimとVimの設定を分けたい場合はコピーすれば可能です。

cp ~/.vimrc ~/config/nvim/init.vim

VimからNeovimに以降するにあたって、プラグイン管理のプラグインを変更するため、私はVimとNeovimの設定は分けて管理することにしています。

プラグインを管理する

VimではNeoBundleを使用していましたが、Neovimではdein.vimを使用します。
参考サイト
github.com
qiita.com

dein.vimのダウンロード方法

dein.vimをダウンロードするには以下のようにします。

$ curl https://raw.githubusercontent.com/Shougo/dein.vim/master/bin/installer.sh > installer.sh
$ sh ./installer.sh ~/.cache/dein

ダウンロード先はお好みですが"~/.vim/plugin" や "~/.config/nvim/plugin"は禁止されています。
インストールはNeovim上で

:call dein#install()

とします。

dein.tomlの書き方

管理するプラグインは通常dein.tomlに書きます。以下に一例を示します。

# dein.toml
# deoplete
[[plugins]]
repo = 'Shougo/deoplete.nvim'

# denite
[[plugins]]
repo = 'Shougo/denite.nvim'

# easy commentout
[[plugins]]
repo = 'tomtom/tcomment_vim'

# expantion copy and paste
[[plugins]]
repo = 'LeafCage/yankround.vim'
hook_add = '''
	nmap p <Plug>(yankround-p)
	xmap p <Plug>(yankround-p)
	nmap P <Plug>(yankround-P)
	nmap gp <Plug>(yankround-gp)
	xmap gp <Plug>(yankround-gp)
	nmap gP <Plug>(yankround-gP)
	nmap <C-p> <Plug>(yankround-prev)
	nmap <C-n> <Plug>(yankround-next)
	'''

基本的にはNeovimと同様にGithubのリポジトリを指定してやれば自動的にインストールされます。プラグインごとの設定はhook_addを利用して設定できます。
dein.tomlの保存場所は基本的に自由ですが、私は~/.config/nvim/dein/に保存しています。

dein.tomlをダウンロードし、読み込むinit.vimの書き方

dein.tomlを書いただけではNeovimは読みにいってくれないので、init.vimに読み込む設定を書きます。ついでなので、dein.tomlがなかったらインストールする設定も書いてしまいます。

" init.vim
" プラグインが実際にインストールされるディレクトリ
let s:dein_dir = expand('~/.cache/dein')
" dein.vim 本体
let s:dein_repo_dir = s:dein_dir . '/repos/github.com/Shougo/dein.vim'

" dein.vim がなければ github から落としてくる
if &runtimepath !~# '/dein.vim'
  if !isdirectory(s:dein_repo_dir)
    execute '!git clone https://github.com/Shougo/dein.vim' s:dein_repo_dir
  endif
  execute 'set runtimepath^=' . fnamemodify(s:dein_repo_dir, ':p')
endif

" 設定開始
if dein#load_state(s:dein_dir)
  call dein#begin(s:dein_dir)
  call dein#add('Shougo/dein.vim')
  call dein#add('Shougo/vimproc.vim', {'build': 'make'})
  call dein#add('Shougo/neocomplete.vim')
  call dein#add('Shougo/neomru.vim')
  call dein#add('Shougo/neosnippet-snippets')
  call dein#add('LeafCage/yankround.vim')
  call dein#add('tomasr/molokai')
  " プラグインリストを収めた TOML ファイル
  " 予め TOML ファイル(後述)を用意しておく
  let g:rc_dir    = expand('~/.config/nvim/dein')
  let s:toml      = g:rc_dir .'/dein.toml'
  "let s:lazy_toml = g:rc_dir . '/dein_lazy.toml'

  " TOML を読み込み、キャッシュしておく
  call dein#load_toml(s:toml,      {'lazy': 0})
  "call dein#load_toml(s:lazy_toml, {'lazy': 1})

  " 設定終了
  call dein#end()
  call dein#save_state()
endif

if dein#check_install()
  call dein#install()
endif

保存して、新たにnvimすれば自動的にdein.tomlとその他プラグインがインストールされます。


参考サイト
Installing Neovim · neovim/neovim Wiki · GitHub
GitHub - Shougo/dein.vim: Dark powered Vim/Neovim plugin manager
NeoBundle から dein.vim に乗り換えたら爆速だった話 - Qiita

【ROS】rvizでMessage removed because it is too old (frame=[/hoge]と表示される

ROSのrvizを使用中にMessage removed because it is too old (frame=[/hoge]というErrorが表示される場合の対処法です。多くの場合、このエラーはrosbag playを使用してbagファイルを再生しながらrvizを使用した時に発生します。ROSは基本的に現在時刻を使ってノードごとの通信をしています。rosbagから流れてくるデータは過去のタイムスタンプが押されたデータなので必然的に現在時刻より古いものになります。ROSは親切にも古い時間のデータを読み飛ばしてくれているのですが、bagファイルを使用してデバッグ等をしたい際はこの機能が邪魔になります。

下記は一例です。

#terminal 1
roscore

#terminal 2
rosparam set /use_sim_time true

#terminal 3
rosbag play hoge.bag --clock

#terminal 4
rosrun rviz rviz

まずroscoreを立ち上げてからrosparamとしてuse_sim_timeをtrueにします。逆だと意味がありません。さらにrosbagを再生する際に--clockとしておきます。
こうすることで、bagファイル上のタイムスタンプの時間が使用されます。

毎回roscoreを立ち上げてからパラメータをセットするのは大変なので、launchを使いたいと思います。launchを利用する際は下のようにしてパラメータを設定します。

<launch>
  <param name="use_sim_time" value="true" />
  <node pkg="hoge" type="piyo" name="foo" />
</launch>

これでlaunchを立ち上げるだけで、use_sim_timeをセットできます。

参考サイト
Error in rosbag play despite setting use_sim_time param - ROS Answers: Open Source Q&A Forum