複数のPCでROSを使う時の設定

# この記事の内容には最新版があります！
コマンドが更新されている（便利になっている）ので，
https://qiita.com/RyodoTanaka/items/0791044a4780543f58fa#_reference-25aeb4b4049b1195b4e1
上記記事をご覧ください！！

# はじめに。。。
はじめまして。RyodoTanakaと申します。
Qiitaで初めての投稿です。QiitaはMarkdownで書けるということで、始めてみました。
Qiitaでは、ROSとかLinux(主にUbuntu)辺りで手に入れたTipsを備忘録として記していきたいと思います。
よろしくお願いします。

# 早速
さて、最初の投稿ですが・・・
#### **複数台のPCでROSを使うことって無いですか？**

ROSを始めてすぐの時は、あまり考えていないと思いますが、いろいろ使っていくと、

- [Gazebo](http://gazebosim.org/)を走らせるPCとプランニング([MoveIt!](http://moveit.ros.org/))を走らせるPCを分けたいなぁ
- 移動ロボットに載せるPCをサーバーにして、手元のPCで状態を確認したいなぁ

なんていう欲求が出てくると思います。**いや、出るはずです。。！**
そんな時、ROSを使えば、[環境変数の設定だけで簡単に実現できる](http://wiki.ros.org/ROS/Tutorials/MultipleMachines)のですが、
それでも設定が面倒くさいです。。。orz
で、結論から言うと、[mu-777さんと全く同じ発想](http://qiita.com/mu-777/items/544c515365df13fbe7fa)だったんですが、これを自動化したいなぁと思って以前作った
**`rosaddress`コマンド**を紹介したいと思います。

#本体
ということで、早速本体です。
コピペして使ってみてください。
使い方とかは、次項で触れます。

```bash:rosaddress.bash
#!/bin/bash
function _func_rosserver() {
	if [ -z "$eth0_addr" ]; then
		echo "No eth0 connection..."
		if [ -z  "$wlan0_addr" ]; then
			echo "No wlan0 connection..."
			export ROS_MASTER_URI=http://localhost:11311
			unset ROS_HOST_NAME
			unset ROS_IP
			echo ""
			echo "            !!CAUTION!! "
			echo "  There're no Ethernet connection."
			echo "  We CAN NOT set this PC to ROS server."
			echo ""
		else
			echo "There are wlan0 connection"
			export ROS_MASTER_URI=http://${wlan0_addr}:11311
			export ROS_HOST_NAME=${wlan0_addr}
			export ROS_IP=${wlan0_addr}
			export PS1="\[\033[41;1;33m\]<ROS_server>\[\033[0m\]\w$ "
		fi	
	else
		echo "There are eth0 connection"
		export ROS_MASTER_URI=http://${eth0_addr}:11311
		export ROS_HOST_NAME=${eth0_addr}
		export ROS_IP=${eth0_addr}
		export PS1="\[\033[41;1;33m\]<ROS_server>\[\033[0m\]\w$ "
	fi

	env | grep "ROS_MASTER_URI"
	env | grep "ROS_HOST_NAME"
	env | grep "ROS_IP"
}

function _func_rosclient() {
	if [ -z "$1" ]; then
		echo $1
		echo "Input the ROS server's IP address.'"
	else
		if [ -z "$eth0_addr" ]; then
			echo "No eth0 connection..."
			if [ -z  "$wlan0_addr" ]; then
				echo "No wlan0 connection..."
				export ROS_MASTER_URI=http://localhost:11311
				unset ROS_HOST_NAME
				unset ROS_IP
				echo ""
				echo "            !!CAUTION!! "
				echo "  There're no Ethernet connection."
				echo "  We CAN NOT set this PC to ROS client."
				echo ""
			else
				echo "There are wlan0 connection"
				export ROS_MASTER_URI=http://$1:11311
				export ROS_HOST_NAME=${wlan0_addr}
				export ROS_IP=${wlan0_addr}
				export PS1="\[\033[44;1;33m\]<ROS_client>\[\033[0m\]\w$ "
			fi	
		else
			echo "There are eth0 connection"
			export ROS_MASTER_URI=http://$1:11311
			export ROS_HOST_NAME=${eth0_addr}
			export ROS_IP=${eth0_addr}
			export PS1="\[\033[44;1;33m\]<ROS_client>\[\033[0m\]\w$ "
		fi
		env | grep "ROS_MASTER_URI"
		env | grep "ROS_HOST_NAME"
		env | grep "ROS_IP"
	fi
}

function _func_roslocal() {
	export ROS_MASTER_URI=http://localhost:11311
	unset ROS_HOST_NAME
	unset ROS_IP
	export PS1="\[\033[42;1;33m\]<ROS_local>\[\033[0m\]\w$ "
	env | grep "ROS_MASTER_URI"
	env | grep "ROS_HOST_NAME"
	env | grep "ROS_IP"
}

function _func_rosexit(){
	export ROS_MASTER_URI=http://localhost:11311
	unset ROS_HOST_NAME
	unset ROS_IP
	export PS1="\u@\h:\w\\$ "
}

function _func_comp_rosaddress(){
	local cur=${COMP_WORDS[COMP_CWORD]}
	if [ "$COMP_CWORD" -eq 1 ]; then
		COMPREPLY=( $(compgen -W "server client local exit" -- $cur) )
	fi
}

function _func_rosaddress() {
	# Get now eth0 or wlan0 IP address
	eth0_addr=$(ip -f inet -o addr show eth0|cut -d\  -f 7 | cut -d/ -f 1)
	wlan0_addr=$(ip -f inet -o addr show wlan0|cut -d\  -f 7 | cut -d/ -f 1)

	if [ $1 = "local" ]; then
		_func_roslocal
	elif [ $1 = "server" ]; then
		_func_rosserver
	elif [ $1 = "client" ]; then
		_func_rosclient $2
	elif [ $1 = "exit" ]; then
		_func_rosexit
	fi
	
}

alias rosaddress=_func_rosaddress
complete -o default -F _func_comp_rosaddress rosaddress
```

# 使い方
まずは、前項にあるリンクから、bashスクリプトをコピペしてください。
ここでは、`rosaddress.bash`としてコピペしたとします。

```bash
$ source rosaddress.bash
```

まずは上記コマンドで`rosaddress`コマンドを有効にしてください。
もし、毎回sourceコマンドを打つのが面倒なら、`~/.bashrc`に追加してください。
使い方は以下の通りです。それぞれのコマンドを打った時の様子も一緒に載せておくので、ご覧ください。

---
- **`rosaddress local`**  
   実行したPCのIPをROS_MASTER_URIに設定し、ROS_IPとROS_HOST_HOSTNAMEを消去します 
   ![Screenshot from 2016-01-29 23:16:43.png](https://qiita-image-store.s3.amazonaws.com/0/110699/a69428dc-ccc2-5ff6-e600-4fbb707e4733.png)  

---

- **`rosaddress server`**  
  実行したPCのIPをROS_MASTER_URIに、ROS_IPとROS_HOSTNAMEも実行したPCのIPに設定します 
  ![Screenshot from 2016-01-29 23:17:00.png](https://qiita-image-store.s3.amazonaws.com/0/110699/08995bf9-c290-4103-dc1c-de962e0be347.png)

---

- **`rosaddress client <server_IP>`**   
   `<server_IP>`をROS_MASTER_URIに、ROS_IPとROS_HOSTNAMEを実行したPCのIPに設定します 
   ![Screenshot from 2016-01-29 23:17:48.png](https://qiita-image-store.s3.amazonaws.com/0/110699/3ff02d8f-a7aa-8926-92c4-b177fd16aef5.png)

---

- **`rosaddress exit`**  
  実行したPCのIPをROS_MASTER_URIに設定し、ROS_IPとROS_HOST_HOSTNAMEを消去した後、rosadressコマンドを抜けます

---


尚、**第2引数まではTab補完が効きます**ので、コマンドの詳細は覚えなくてOKです。

# やってること
まず、PCの`wlan0`に設定されているIPを確かめに行きます。
これが設定されていなかった場合、`eth0`に設定されているIPを確かめに行きます。
`wlan0`もしくは`eth0`にIPが設定されていた場合には、`wlan0`のIP優先で、取得したIPアドレスを自身のPCをのアドレスとして環境変数を設定してゆきます。
`wlan0`、`eth0`のどちらにも設定が無かった場合には、自身のIPアドレスを取得できないものとしてエラーを返します。(rosaddress local コマンドはエラーを返しません)

紹介したコマンドを動かすエイリアス設定を行い、各エイリアスの引数等で環境変数を設定。更に、それぞれのエイリアスに補完機能をつけているといった感じです。

# まとめ
ってことで、僕は非常に便利に使っているわけですが、**zshは無いのか？**という声が聞こえてきます。
残念ながら、現在はありません（僕がzshを使ってないからです）。。。orz
次の春休みにでも書こうかな(zsh使いになろうかな)？と思っていますので、またその時に投稿したいと思います。