M1 MacでODriveを動かすには

#エラー内容
新しく買ったM1チップMacbook Pro上でODriveを使おうと，[ODrive Documentation:Getting Started](https://docs.odriverobotics.com/)に従って

```zsh
$ odrivetool
```
として起動しようとすると以下のようにエラーが出ました．
従来のIntelチップ版ではこのエラーは出ないですし，その解決方法を調べてもほとんど出てこないので，今回試した解決過程を記しておきます．
<img width="600" alt="Screen Shot 2020-05-21 at 5.31.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/b50fe42b-2dcf-892f-3fe3-b9361ca09e2d.png">

#環境
- Apple M1 chip Macbook Pro
- macOS Big Sur 11.2.3

#解決法
問題は，`odrivetool`を立ち上げる中身で`pyusb`というライブラリを使用しているのですが，そのときに使用される`libusb`というパッケージが上手く見つけられていないということらしいです．
`libusb`はHomebrewによって以下のようにインストールするようにドキュメントに書かれているのですが，M1チップとIntelチップではHomebrewのパスが異なる[^1]ので，おそらくこの違いのせいで`pyusb`から上手く見つけられていないのではないかと思います．

```zsh
$ brew install libusb
```

## Homebrew経由でインストールしたPythonを使う
Pythonのインストールには様々な方法があり[このサイト](https://qiita.com/ms-rock/items/72b8f1abc661c539bb09)によくまとまっています．
Python環境作りのベストプラクティスが何かは分かりませんが，個人的には`pyenv`+`venv`でプロジェクトごとに環境を作っていました．
しかしあくまで推測ですが，今回の問題はHomebrewのパッケージを上手く使えていないということなので，Homebrew経由で，`/opt/homebrew`以下にインストールしたPythonを使うという方針で行きます．そのPythonなら，`opt/homebrew/opt/libusb`を見つけられるのではないかという希望を込めて．
この[issue](https://github.com/pyusb/pyusb/issues/355)にもそのように書かれているので，おそらくはできるのだと思います．

インストールは，以下のコマンドを叩いて最新のPython3.9をインストールすれば良いです．

```zsh
$ brew install python
```

ODriveの[インストールページ](https://docs.odriverobotics.com/)には，
> As of Oct 2020, Matplotlib (required by odrivetool) had not been updated to work with 3.9, so please use 3.8.6.

と書いてあるので，`brew install python@3.8`としてPython3.8を指定してインストールした方がいいのかもしれないのですが，そうすると逆にM1チップではnumpyのビルドに失敗します．(~~4/11/2021現時点でMatplotlibは動くので問題ないでしょう~~ [このissue](https://github.com/odriverobotics/ODrive/issues/561#issuecomment-818638037)で大丈夫だと答えてもらったので問題ないでしょう)



現在のシェルでこのpythonを使うためにはパスを通す必要があります．
pyenvと同じ感じでディレクトリに入ったときにpythonを切り替えられれば理想ですが，それを模して，以下のようなシェルスクリプトを作っておけば便利でしょう．

```zsh:setup.sh
# use python3.9 installed from homebrew
export PATH=/opt/homebrew/opt/python@3.9/libexec/bin:$PATH
```
これを実行することで，さっきインストールしたPython3.9が使えるようになります．

```zsh
$ . ./setup.sh
$ which python
/opt/homebrew/opt/python@3.9/libexec/bin/python
$ python --version
Python 3.9.4
```

####参考サイト
- [Python3インストール（Mac編）](https://qiita.com/ms-rock/items/72b8f1abc661c539bb09)
- [M1 MacのPythonデフォルトを3.9にする](https://dev.classmethod.jp/articles/make-3-9-as-python-default-on-m1-mac/)


## venvにpipでODriveをインストール
あとは[公式ドキュメント](https://docs.odriverobotics.com/)の通り進めていくだけです．venvを作って，pipでODriveをインストールしましょう．

```zsh
$ python -m venv .venv
$ source .venv/bin/activate
(.venv)$ pip install --upgrade odrive
```

すると，先程のエラーはなく`odrivetool`を起動することができました！
<img width="600" alt="Screen Shot 2020-05-21 at 5.31.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/9d99cb72-4b9f-c438-986a-e5af071bc39a.png">

# [Troubleshooting] IPythonのパスが間違っている
たまに，先ほどのエラーとは別に，以下のようなWarningが出ることがあります．
<img width="600" alt="Screen Shot 2020-05-21 at 5.31.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/505262/63c30b6c-6fca-dbea-2e35-d2f739926c02.png">
これは，`odrive`の中身で起動させる`IPython`が，venvの中のものと別のものを起動させてしまっているというWarningです．
試しに

```zsh
$ which odrivetool
/opt/homebrew/bin/odrivetool
```
として調べてみると，venvの中でpipで入れた`odrive`を差しておらず，別の場所にある(おそらく色々といじっているときに入れたであろうhomebrew以下の)`odrive`を叩いてしまったがために，その中身で起動する`IPython`もvenv外のものになってしまっています．
これを，venvをactivateしている状態で起動してしまったので，上のようなWarningが出ているのではないかと思います．

これを解消するには，以下のように[`rehash`](http://x68000.q-e-d.net/~68user/unix/pickup?rehash)コマンドを打ってコマンドを登録し直しましょう．

```zsh
$ rehash
```
そうすると，venv内の`odrive`が叩かれるようになり，正しく起動するようになります．

####参考サイト
- [brew/pip3 install ipython の違い](https://oxon.hatenablog.com/entry/2020/06/11/183118)

[^1]: M1チップでは`/opt/homebrew`以下に，Intelチップでは`/usr/local`にインストールされます．([参考](https://docs.brew.sh/Installation))