RaspberryPi で沢山モータを動かしてみたくてサンプルを作ってみました。
ここにメモを残します。
コード
import Adafruit_PCA9685 import json import time pwm = Adafruit_PCA9685.PCA9685() pwm.set_pwm_freq(60) def set_servo_angle(channel, angle, pattern): pulse_min = 150 # 最小パルス幅(0度のとき) pulse_max = 650 # 最大パルス幅(180度のとき) pulse_width = pulse_min + (angle / 180.0) * (pulse_max - pulse_min) print(f"pattern: {pattern}, channel: {channel}, pulse_width: {pulse_width}") pwm.set_pwm(channel, 0, int(pulse_width)) return def move_servos(channels, start_angles, end_angles, speeds, pattern): max_steps = max(abs(end - start) for start, end in zip(start_angles, end_angles)) steps = [abs(end - start) for start, end in zip(start_angles, end_angles)] directions = [1 if end > start else -1 for start, end in zip(start_angles, end_angles)] current_angles = start_angles[:] for step in range(max_steps): for i, channel in enumerate(channels): print(f"range: {steps[i]} / {channel}") if step < steps[i]: current_angles[i] += directions[i] set_servo_angle(channel, current_angles[i], pattern) time.sleep(1 / min(speeds)) def motion(motion_file): json_load = json.load(open(f"{motion_file}.json", 'r')) for i in (json_load): move_servos( channels = json_load[i]['channels'], start_angles = json_load[i]['start_angles'], end_angles = json_load[i]['end_angles'], speeds = json_load[i]['speeds'], pattern = motion_file ) def main(): while True: motion("pattern_01") motion("pattern_02") motion("pattern_03") if __name__ == '__main__': main()
モーションファイル
pattern_01.json
{ "a": { "channels": [0, 1, 2, 3, 4, 5, 6, 7, 8], "start_angles": [90, 90, 90, 90, 90, 90, 90, 90, 90], "end_angles": [10, 45, 135, 150, 20, 30, 0, 0, 0], "speeds": [20, 50, 20, 30, 40, 90, 10, 10, 10] }, "b": { "channels": [0, 1, 2, 3, 4, 5, 6, 7, 8], "start_angles": [10, 45, 135, 150, 20, 30, 0, 0, 0], "end_angles": [160, 145, 35, 50, 120, 130, 20, 20, 20], "speeds": [20, 50, 20, 30, 40, 90, 100, 10, 10] }, "c": { "channels": [0, 1, 2, 3, 4, 5, 6, 7, 8], "start_angles": [160, 145, 35, 50, 120, 130, 20, 20, 20], "end_angles": [90, 90, 90, 90, 90, 90, 90, 90, 90], "speeds": [10, 50, 20, 30, 40, 50, 10, 10, 10] } }
pattern_02.json
{ "a": { "channels": [0, 1, 2, 3, 4, 5, 6, 7, 8], "start_angles": [90, 90, 90, 90, 90, 90, 90, 90, 90], "end_angles": [0, 0, 0, 0, 0, 180, 180, 180, 180], "speeds": [150, 150, 150, 150, 150, 150, 150, 150, 150] }, "b": { "channels": [0, 1, 2, 3, 4, 5, 6, 7, 8], "start_angles": [0, 0, 0, 0, 0, 180, 180, 180, 180], "end_angles": [180, 180, 180, 180, 180, 0, 0, 0, 0], "speeds": [150, 150, 150, 150, 150, 150, 150, 150, 150] }, "c": { "channels": [0, 1, 2, 3, 4, 5, 6, 7, 8], "start_angles": [180, 180, 180, 180, 180, 0, 0, 0, 0], "end_angles": [90, 90, 90, 90, 90, 90, 90, 90, 90], "speeds": [150, 150, 150, 150, 150, 150, 150, 150, 150] } }
pattern_03.json
{ "a": { "channels": [0, 1, 2, 3, 4, 5, 6, 7, 8], "start_angles": [90, 90, 90, 90, 90, 90, 90, 90, 90], "end_angles": [0, 0, 0, 0, 0, 180, 180, 180, 180], "speeds": [10, 10, 10, 10, 10, 10, 10, 10, 10] }, "b": { "channels": [0, 1, 2, 3, 4, 5, 6, 7, 8], "start_angles": [0, 0, 0, 0, 0, 180, 180, 180, 180], "end_angles": [180, 180, 180, 180, 180, 0, 0, 0, 0], "speeds": [10, 10, 10, 10, 10, 10, 10, 10, 10] }, "c": { "channels": [0, 1, 2, 3, 4, 5, 6, 7, 8], "start_angles": [180, 180, 180, 180, 180, 0, 0, 0, 0], "end_angles": [90, 90, 90, 90, 90, 90, 90, 90, 90], "speeds": [10, 10, 10, 10, 10, 10, 10, 10, 10] } }