なんとなく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)