LoginSignup
2
2

More than 3 years have passed since last update.

Donkey Car から PCA9685 を取っ払って、ESC・サーボをラズパイに直結する

Last updated at Posted at 2020-02-01

はじめに

Donkey Car はESC・サーボの制御にPCA9685(16ch PWM出力ボード)を使用しています。
しかし、Raspberry Pi単体でもサーボ制御信号(PWM信号)は出力できるはずです。
PCA9685はいらない子なのではないか?
そう思って調べてみたところ、割と簡単に外せました。

ラズパイのPWM出力

ラズパイからPWM出力する方法はいくつかあります。
pythonから利用しやすいものだと、RPi.GPIOpigpio などがあります。
RPi.GPIO はソフトウェアでやっているのか、精度が悪いです。パルス幅が安定せず、サーボがプルプルしてします。(←聞いた話)
pigpio が本命でしょうか。

しかし、manage.pyを読んでみると、ServoBlaster を利用している箇所があります。これを使えば、Donkey Car 用の Parts を作らなくてもよさそうです。

というわけで、ServoBlaster を使うことに決めました。

ServoBlaster ビルド

apt で拾ってこれないので、git clone して make します。

cd ~
git clone https://github.com/richardghirst/PiBits.git
cd ~/PiBits/ServoBlaster/user/
make servod

make installでサービス化できるようなのですが、どうもうまく動かないので推奨しません(後述))

ServoBlaster 起動

sudo ~/PiBits/ServoBlaster/user/servod --idle-timeout=2000 --step-size=4

で起動します。

オプション--idle-timeout=2000 は、使ってないときにサーボへの出力を止めるオプションです。これにより、manage.py を動かしてないときの消費電力が若干減ると思います。

オプション--step-size=4 は、STEERING_LEFT_PWMなどの1が何マイクロ秒相当かという設定です。このオプションにより、PCA9685の場合とほぼ同じPWM設定値を流用することができます! (ほぼ同じですが、若干違います(後述))

manage.py 追記

manage.pyの、elif cfg.DRIVE_TRAIN_TYPE == "SERVO_HBRIDGE_PWM":ブロックの後ろに、下記コードを追加します。

    elif cfg.DRIVE_TRAIN_TYPE == "SERVO_ESC_ONBOARD":
        from donkeycar.parts.actuator import ServoBlaster, PWMSteering, PWMThrottle

        steering_controller = ServoBlaster(cfg.STEERING_CHANNEL)
        steering = PWMSteering(controller=steering_controller,
                                        left_pulse=cfg.STEERING_LEFT_PWM,
                                        right_pulse=cfg.STEERING_RIGHT_PWM)

        throttle_controller = ServoBlaster(cfg.THROTTLE_CHANNEL)
        throttle = PWMThrottle(controller=throttle_controller,
                                        max_pulse=cfg.THROTTLE_FORWARD_PWM,
                                        zero_pulse=cfg.THROTTLE_STOPPED_PWM,
                                        min_pulse=cfg.THROTTLE_REVERSE_PWM)

        V.add(steering, inputs=['angle'])
        V.add(throttle, inputs=['throttle'])

軽く説明すると、DRIVE_TRAIN_TYPESERVO_ESC_ONBOARD というタイプを追加して、具体的にはこーしてねというのを書いてます。

myconfig.py 修正

下記定数3つを修正します。

DRIVE_TRAIN_TYPE = "SERVO_ESC_ONBOARD"
STEERING_CHANNEL = 11           #pin number on the Raspberry Pi
THROTTLE_CHANNEL = 13           #pin number on the Raspberry Pi

ここのピンNo.は、GPIOの番号ではなく、1~40の物理ピン番号であることに注意してください。
また、標準で使えるのは 7,11,12,13,15,16,18,22 だけです。
ここで11と13を選んだのは、I2C接続も挿さってる場合に挿しやすい場所だったからです。
この辺はお好みでどうぞ。

配線

電源とGNDと信号線が繋がっていればオッケーなので簡単です。

ラズパイ ESC サーボ 備考
11 GPIOでいうと17
13 GPIOでいうと27
ESCとサーボの赤同士をつなげる
ESCとサーボの黒同士をつなげる

これを
DSC00361.JPG
こうして
servo_01.jpg
こうじゃ
servo_02.jpg

ラズパイとサーボ・ESCのGNDが繋がってないような気がしますが、電源側で繋がってるので問題ありません。

ラズパイとサーボ・ESCの電源は繋がないのが正解です。(ESCが電源を供給して、サーボがそれを使っています。)

ラズパイは3.3V I/Oなので、サーボ・ESCからみるとI/O電圧が足りませんが、だいたい閾値がVcc/2のことが多いので、まあOKだと思います。
最近のBEC 6VのESCを積んだラジコンだと不安定になるかも???
ご心配ならI/O電圧を変換するナニカを挟んでくださいませ。

とりあえず、手元の Robocar Store で買ったDonkeyCar(のベース車両であるHSP 94186)では動いています。

走行

あとはいつものように走行するだけです!

cd ~/mycar
python manage.py drive

(実は、「Webコントローラーから制御できてるな」という確認までしただけで、教師走行や自律走行は試しておりません。。。)

細かい話:PWM設定値

PWM設定値の正確な値の話をすると、PCA9685 の場合の1は、パルス間隔を4096で割った値です(12bit PWMなので4096で割るんですヨ)。DonkeyCarではPWM周波数を60Hzにしているので、パルス間隔は1/60です。ということから計算すると

1,000,000[μs]/60/4096 ≒ 4.069[μs]

となります。

一方、ServoBlaster の場合は設定値がマイクロ秒単位で設定できて、設定どおり4マイクロ秒です。

1.7%ぐらいの誤差となります。ニュートラルが370だったとすると、376ぐらいに変更する必要があります。

おまけ:キャリブレーション

https://docs.robocarstore.com/guide/calibrate/ でやるキャリブレーションはPCA9685に接続されていることが前提なので、この記事の配線方法にすると使えません。

PWM出力を手動で行うことが、下記コマンドでできます。

echo P1-11=370 > /dev/servoblaster 

一応説明しておくと、P1は固定で、11がピン番号、370が出力値です。

課題:servodのサービス化

ServoBlasterをmakeしたときのディレクトリで

sudo make install

をすると、実行ファイルservod/usr/local/sbin/ にコピーされ、起動用の /etc/init.d/servoblaster が作成されます。

起動オプション --step-size=4 は、/etc/init.d/servoblasterOPTSに追記する形で

OPTS="--idle-timeout=2000 --step-size=4"

としておけばよさそうです。

しかし、どうもOS起動後に --step-size=4 が効いてないような動作になります。
psコマンドで見ると引数は渡されているっぽいんですけれども。

sudo /etc/init.d/servoblaster restart

でサービスの再起動をしてみると、なぜか /dev/servoblaster が見えなくなってしまいます。
psコマンドで見るとプロセスは生きているっぽいんですけれども。

とりま、stop start で正常動作するようにはなります。

sudo /etc/init.d/servoblaster stop
sudo /etc/init.d/servoblaster start

OS起動後にコマンド打たなきゃいけないなら、サービス化しなくてもいいんじゃないかと思います。
サービス化してもちゃんと動くようにしたいんですけれどもね・・・

おわりに

Donkey Car から PCA9685 を外す方法を紹介しました。

なんで設定が簡単にできるようになってないのか不思議です。しかし、ソースを読んでると、なんかこのぐらいの改造は設定のうちというふいんきを感じます。

この記事を書いた後、 ~/projects/donkeycar/donkeycar/parts/actuator.py の中に PiGPIO_PWM というクラスを見つけてしまいました。pigpio も似たような「設定」で使うことができそうです。

追記:pigpioを使う方法を書きました → https://qiita.com/rukihena/items/b3d16c2bf6e1a62b0c92

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2