Raspberry Pi Build HATでラジコンカーを作ってみた

スポンサーリンク

なんとなくRaspberry Pi Build HATを使ってラジコンカーを作りたくなったので、次はラジコンカーを作成。そのときの備忘録です。

作ったラジコンカー↓


まあまあシンプルに作れたので満足。 もっと部品点数を減らすことはできそうだけど、モーターをしっかり固定しないと簡単に動かなくなるし、ギアを使わないと遅すぎる。

主な材料、環境

ハード: Raspberry Pi 3 model B、Raspberry Pi Build HAT、F710ワイヤレス ゲームパッド 、レゴ、 ラズパイを固定するメイカープレート(3Dプリンタ出力)、バッテリー、バッテリーとBuild HATをつなぐケーブル
OS: Raspberry Pi OS (32bit)

レゴ組み立て方メモ

①黄色いプレートにモーターを固定
ギアは2ポッチの長さの棒でモーターに付ける。

②後輪を組み立てて、さっきの①と接続

③補強用のパーツを組み立てる
↓これを2つ

モーターにセット

④反対側にもセットして、後輪完成

⑤次は前輪部分を作成。
写真は黒いパーツの位置を間違えてる。本当は一つ内側。

⑥前輪の補強パーツ作成

⑦さっき作った⑥を黄色いプレートにセット、その後、補強パーツ⑥をセット

⑧モーターと⑤を水色のブロックで接続

ここまでで前輪と後輪周辺は完成

⑨ラズパイをメイカーブレードに固定して、適当に組み立て

上段の青枠を作成

中段と下段の青枠も作成

⑩先ほど作った⑨を⑧に接続

⑪黒いパーツで左右後ろを補強

完成

Build HATとモーターの接続

ポート 接続するモーター
A 後輪用 Mアンギュラーモータ
B 前輪用 Mアンギュラーモーター

ゲームパッドでの動かし方

ボタン 内容
左スティック 上で前進、下で後退。どのくらい押し込むかで速度が変わる
X 前輪を左に向ける
B 前輪を右に向ける

プログラム

car.pyと名前を付けて保存し、実行。
run_to_positionを非同期で高頻度で呼ぶと例外が発生するので、ボタンを押したときだけ呼び出すようにした。
モーターに対して、plimit, biasを呼び出すことで反応が悪さを改善している。

import os

import pygame
from buildhat import Motor, Hat
from pygame.locals import *


def get_joy_axes_data():
    axis_lx = round(joy.get_axis(0), 3)
    axis_ly = round(joy.get_axis(1), 3)
    axis_rx = round(joy.get_axis(3), 3)
    axis_ry = round(joy.get_axis(4), 3)
    hat_x = joy.get_hat(0)[0]
    hat_y = joy.get_hat(0)[1]
    axes_data = {
        "L": (axis_lx, axis_ly),
        "R": (axis_rx, axis_ry),
        "HAT_X": hat_x,
        "HAT_Y": hat_y,
    }
    print(axes_data)
    return axis_lx, axis_ly, axis_rx, axis_ry, hat_x, hat_y


def init_motor(motor):
    motor.release = False
    motor.set_default_speed(100)
    motor.plimit(1.0)
    motor.bias(0.4)


os.environ["SDL_VIDEODRIVER"] = "dummy"
pygame.init()

pygame.joystick.init()
joy = pygame.joystick.Joystick(0)
joy.init()

hat = Hat()
print('Hat voltage = %f' % hat.get_vin())

motor_a = Motor('A')
motor_b = Motor('B')
init_motor(motor_a)
init_motor(motor_b)

while True:
    pygame.time.wait(30)
    for e in pygame.event.get():
        if e.type == pygame.locals.JOYAXISMOTION or e.type == pygame.locals.JOYHATMOTION:
            (axis_lx, axis_ly, axis_rx, axis_ry, hat_x, hat_y) = get_joy_axes_data()
            if axis_ly < -0.2:
                motor_a.start(-100 * -axis_ly)
            elif axis_ly > 0.2:
                motor_a.start(100 * axis_ly)
            else:
                motor_a.stop()
        if e.type == pygame.locals.JOYBUTTONDOWN:
            print('BUTTON %d DOWN' % e.button)
            if e.button == 1:
                motor_b.run_to_position(-60, blocking=False)
            if e.button == 2:
                motor_b.run_to_position(60, blocking=False)
        elif e.type == pygame.locals.JOYBUTTONUP:
            print('BUTTON %d UP ' % e.button)
            if e.button == 1 or e.button == 2:
                motor_b.run_to_position(0, blocking=False)

www.sato-susumu.com

www.sato-susumu.com

www.sato-susumu.com