macOS Mojaveにros kineticをインストール

# 環境
- MacBook Pro (13-inch, 2017)
- macOS Mojave
- Pythonは`pyenv`でインストールしたものを使ったら上手くいかなかったので、アンインストールして、macOSにデフォルトで入ってい`python2`を用いた。(`pyenv global system`としても無理だったので）

![gazebo_test.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146448/28db1109-4ed5-507d-5a38-c17df0ffc384.gif)

# 参考
https://gist.github.com/entire/5b290028d52933d0532f45923f6bc896

# 下準備
[ROS公式インストール](http://wiki.ros.org/kinetic/Installation/OSX/Homebrew/Source)にしたがってインストールしたので、以前独立して`brew install gazebo9｀をインストールしたせいか、コンフリクトが起きてしまった。

[ここ](https://answers.ros.org/question/104416/uninstall-ros-fully-on-os-x/)にあるように、まずは綺麗にros関係のdependenciesを削除する。

```
rosdep db | awk '{if ($3) print $3}' | { while read package; do [ "$package" == "->" ] || (brew info $package &> /dev/null && echo "brew remove $package") || (pip list | grep $package &> /dev/null  && echo "pip uninstall $package") || echo "# $package is neither brew formula or a python package"; done; }
```


# インストール
## Homebrew
```
$ brew update
$ brew install cmake
$ brew tap ros/deps 
```

最後の１行がうまくいかないので、代替として以下を使う。

```
brew tap nagakiran/deps
``` 

そのほかのdependenciesをtapする。

```
$ brew tap osrf/simulation   # Gazebo, sdformat, and ogre
$ brew tap homebrew/core # VTK5
```

## Pythonにhomebrewでインストールしたものの場所を教える
```
$ mkdir -p ~/Library/Python/2.7/lib/python/site-packages
$ echo "$(brew --prefix)/lib/python2.7/site-packages" >> ~/Library/Python/2.7/lib/python/site-packages/homebrew.pth
$ brew install python  # brew Python comes with pip and is installed as python2
$ sudo -H python2 -m pip install -U pip  # Update pip
$ sudo -H python2 -m pip install wxPython # Install python-wxtools
```

`rosdep`をpipでインストールする。　

```
$ sudo -H python2 -m pip install -U wstool rosdep rosinstall rosinstall_generator rospkg catkin-pkg sphinx
$ sudo -H rosdep init
$ rosdep update
```

```
$ mkdir ~/ros_catkin_ws
$ cd ~/ros_catkin_ws
```


```
$ rosinstall_generator desktop_full --rosdistro kinetic --deps --wet-only --tar > kinetic-desktop-full-wet.rosinstall
$ wstool init -j8 src kinetic-desktop-full-wet.rosinstall
```

`rosdep`で足りないdependenciesをインストールするわけだが、これだと上手くいかないと思うので、
これを

```
$ rosdep install --from-paths src --ignore-src --rosdistro kinetic -y
```
こうする

```
$ rosdep install --from-paths src --ignore-src --skip-keys "python-wxtools google-mock boost" --rosdistro kinetic -y
```
で`python-wxtools`や`google-mock`、また後々インストールする`Boost`を無視する。

# ビルド
一旦`./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release
`とやってみる。すると多くのエラーが出てくる。

# デバッグ

### `boost/tr1/unordered_set.hpp not found`
`boost`の新しいversionだと`tr1`が廃止になっているため、古いバージョンをインストールする。

#### 失敗例
`brew`には１つ前の古いバージョンとして、1.60しかない。このバージョンでインストールすると、boostに依存するいくつかのライブラリでエラーが起きる。

```
brew install boost@1.60
cp -r /usr/local/Cellar/boost@1.60/1.60 /usr/local/Cellar/boost/
brew switch boost 1.60
```

#### 成功例
##### 1. [boostのホームページ](https://www.boost.org/users/download/#live)から`1.64.0`をダウンロードする。
##### 2. 解凍
```
tar -xzf boost_1_64_0.tar.gz
cd boost_1_64_0
```

##### 3. 環境設定
```
./bootstrap.sh
```
すると、デフォルトでは`/usr/local/include/boost`にヘッダーファイルが、`/usr/local/lib`にライブラリがインストールされる。もし、インストール先を変更したい場合は、`--prefix=/some/dir/you/would/like/to/prefix` で好きな場所に変更できる。


##### 4. ビルド
```
./b2
```

##### 5. インストール
```
./b2 install
```

ビルドした`boost`の場所を`cmake`に教えてあげればOK.
`vim ~/ros_catkin_ws/src/roscpp_core/cpp_common/CMakeLists.txt`で開いて、

```
SET (Boost_INCLUDE_DIR "/usr/local/include")
SET (Boost_LIBRARY_DIR "/usr/local/lib")
```
もしかしたら、
`SET (BOOST_ROOT "/boost/1.64.0/をダウンロード/したディレクトリ/のパス")`も必要かもしれない。


### ImportError: No module named sipconfig Could not find SIP
`sip`は`brew`で入っているはずですが、これは`python3`用なので、`python2`用にソースからビルドします。

```
$ wget https://netix.dl.sourceforge.net/project/pyqt/sip/sip-4.19.1/sip-4.19.1.tar.gz
$ tar zxf sip-4.19.1.tar.gz
```

```
$ cd sip-4.19.1
```

```
$ python configure.py --deployment-target=10.12 --destdir=$(brew --prefix)/lib/python2.7/site-packages --incdir=$(brew --prefix)/include/
```

```
$ make
$ make install
```




デバッグしている最中に、何回も`./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release`コマンドを叩くと思うが、変更を加えて反映されないことがある。そんなときは、既に一度ビルドした中間生成ファイルを削除するとよい。
`~/ros_catkin_ws/devel_isolated/`と`~/ros_catkin_ws/build_isolated/`を削除してあげると、変更が反映されるはず。


### error: use of undeclared identifier 'logWarn'
`~/ros_catkin_ws/src/geometry2/tf2/src/buffer_core.cpp` に含まれる
`logWarn`を`CONSOLE_BRIDGE_logWarn`、`logError`を`CONSOLE_BRIDGE_logError`に置換。

### Building package “Geometric shapes” fails with error “ld: library not found for -lassimp”. 
`~/ros_catkin_ws/src/geometric_shapes/CMakeLists.txt`の

```
target_link_libraries(${PROJECT_NAME} ${ASSIMP_LIBRARIES} ${QHULL_LIBRARIES} ${catkin_LIBRARIES} ${console_bridge_LIBRARIES} ${Boost_LIBRARIES})
```
部分を直接ライブラリの箇所を指定してあげる。

```
target_link_libraries(${PROJECT_NAME} /usr/local/lib/libassimp.dylib ${QHULL_LIBRARIES}
```


### brew packageのバージョンを変更するには
インストールした`cmake`が新しぎたバージョンだったので、前のバージョンに戻す必要があった。
`/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/`以下に入っているパッケージの調理方法(Formulaファイル）、例えば`cmake.rb`を古いコミットに`checkout`する。

```
git log cmake.rb
```

```
git checkout f1b05ae43b3546fff661f0fa5909da21a4c7d620 cmake.rb
brew install cmake
```

### error: no member named 'strcoll' in the global namespace using ::strcoll;
[参考資料](https://github.com/ros/rosdistro/issues/13333) 
エラーの理由は、異なる`string.h`をインクードしてたので、その問題となっている`UUID`の部分を少し修正する。

```
brew install ossp-uuid
```

そして、`~/ros_catkin_ws/src/cmake_modules/cmake/Modules/FindUUID.cmake`に含まれる

```
find_path(UUID_INCLUDE_DIRS uuid/uuid.h)`
```
を

```
find_path(UUID_INCLUDE_DIRS ossp/uuid.h)
```
に変更する。　

### kinetic Could not find a configuration file for package "OpenCV" that is compatible with requested version "3".
brew でインストールしたopencvのバージョンをあげる、もしくは下げる。

```
brew install opencv@3
cp -r /usr/local/Cellar/opencv@3/3.4.5_2 /usr/local/Cellar/opencv/3.4.5_2
brew switch boost 3.4.5_2
```

そして、リンク

```
brew ln opencv3 --force
```

### no member named 'make_array' in namespace 'boost::serialization'
[](https://stackoverflow.com/questions/44534516/error-make-array-is-not-a-member-of-boostserialization)
以下のファイルに１行`include`を付け足す。

```
/usr/local/include/boost/numeric/ublas/storage.hpp
/usr/local/include/boost/numeric/ublas/matrix.hpp
```

```
#include <boost/serialization/array_wrapper.hpp>
```


## Failed to process package 'opencv3': error: no member named       'ImmediateModeRenderingOff' in 'vtkPolyDataMapper'

`~/ros_catkin_ws/src/opencv3/`消す。　

## camera_calibration_parsers error: a space is required between consecutive right angle brackets (use '> >')
`camera_calibration_parsers`の`CMakeLists.txt`に以下を加える。

```
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")`
```

## hb.h file not found
```
brew install harfbuzz
```
してから、pangoパッケージの全てに含まれる以下の部分を変更する
VSCode でとりあえず`src`以下を全検索するべし。

```
#include <hb.h> 
```
を

```
#include <harfbuzz/hb.h>
```
に変更する。

##  ld: library not found for -lflann
https://stackoverflow.com/questions/53776238/building-point-cloud-library-pcl-on-macos-x-mojave-error-ld-library-not-foun

`vim /usr/local/Cellar/pcl/1.9.1_4/share/pcl-1.9/Modules/FindFLANN.cmake`
以下を追加。

```
set(FLANN_LIBRARIES /usr/local/lib/libflann.dylib /usr/local/lib/libflann_cpp.dylib)
set(FLANN_FOUND TRUE)
```


### 最後に１つ`laser_geometry`でエラーが出てたはずだが思い出せない、、、
今までのエラーの対処法でいけるはず

# sourceするのを忘れずに
```
source ~/ros_catkin_ws/install_isolated/setup.bash
```


# 走らせる
## turtlesim
```Terminal1
roscore
```

```Terminal2
rosrun turtlesim turtlesim_node
```

するとエラーが発生する

```
dyld: Library not loaded: librospack.dylib
```

`~/ros_catkin_ws/install_isolated/lib`に入っているはずだが、上手く見つけられていないだけ。
対処法は、2つ。

簡単な方法は、
`~/ros_catkin_ws/install_isolated/bin/rosrun`を編集して、2行目に以下を加える

```
export DYLD_LIBRARY_PATH=$DYLD_LIBRARY_PATH:/Users/kandai/ros_catkin_ws/install_isolated/lib
```

もしくは、catkin_make_isolatedするときに引く数で渡す。

```
catkin_make_isolated --install -DCMAKE_MACOSX_RPATH=ON -DCMAKE_INSTALL_RPATH="/Users/kandai/ros_catkin_ws/install_isolated/lib"
```



# rviz
```
OGRE EXCEPTION(7:InternalErrorException): Cannot find serializer implementation for current version
```

というエラーが出る。これは`ogre`のバージョンが1.7だからである。kineticは1.8以上。
brewでは1.9がインストールされているので、switchして1.9を使う。


# rostopic
```
rostopic list
```
とやると

```
Fatal Python error: PyThreadState_Get: no current thread
Abort trap: 6
```

とエラーになる。
これはrosのビルドをするときに、systemのpythonを使っているから。brewのpythonを指定すべき
`catkin_make_isolated`　の引数として、

```
-DPYTHON_INCLUDE_DIR="/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Headers"
-DPYTHON_LIBRARY="/usr/local/Cellar/python/2.7.13/Frameworks/Python.framework/Versions/2.7/lib/libpython2.7.dylib"
```
を追加すればオーケー。