|
| 1 | +# SPDX-FileCopyrightText: 2018 Dave Astels for Adafruit Industries |
| 2 | +# |
| 3 | +# SPDX-License-Identifier: MIT |
| 4 | + |
| 5 | +""" |
| 6 | +Continuous servo based walking/waddling/etc robot. |
| 7 | +
|
| 8 | +Adafruit invests time and resources providing this open source code. |
| 9 | +Please support Adafruit and open source hardware by purchasing |
| 10 | +products from Adafruit! |
| 11 | +
|
| 12 | +Written by Dave Astels for Adafruit Industries |
| 13 | +Copyright (c) 2018 Adafruit Industries |
| 14 | +Licensed under the MIT license. |
| 15 | +
|
| 16 | +All text above must be included in any redistribution. |
| 17 | +""" |
| 18 | + |
| 19 | +import time |
| 20 | +from adafruit_crickit import crickit |
| 21 | + |
| 22 | +tail = crickit.dc_motor_1 |
| 23 | + |
| 24 | +# Each servo corresponds to one of the legs |
| 25 | +front_right = crickit.continuous_servo_1 |
| 26 | +front_left = crickit.continuous_servo_2 |
| 27 | +rear_right = crickit.continuous_servo_3 |
| 28 | +rear_left = crickit.continuous_servo_4 |
| 29 | + |
| 30 | +# Useful groups of legs |
| 31 | +all_legs = [front_right, front_left, rear_right, rear_left] |
| 32 | +front_legs = [front_right, front_left] |
| 33 | +rear_legs = [rear_right, rear_left] |
| 34 | +right_legs = [front_right, rear_right] |
| 35 | +left_legs = [front_left, rear_left] |
| 36 | + |
| 37 | +# The sign (+1/-1) for forward motion for each servo |
| 38 | +direction_values = {front_right: +1, |
| 39 | + front_left: -1, |
| 40 | + rear_right: +1, |
| 41 | + rear_left: -1} |
| 42 | + |
| 43 | +# Tweak the pwn ranges for each servo so that throttle of 0 stops the motor |
| 44 | +pwm_ranges = {front_right: (500, 2400), |
| 45 | + front_left: (500, 2400), |
| 46 | + rear_right: (500, 2400), |
| 47 | + rear_left: (500, 2400)} |
| 48 | + |
| 49 | + |
| 50 | +def init(): |
| 51 | + for leg in all_legs: |
| 52 | + limits = pwm_ranges[leg] |
| 53 | + leg.set_pulse_width_range(min_pulse=limits[0], max_pulse=limits[1]) |
| 54 | + leg.throttle = 0 |
| 55 | + |
| 56 | + |
| 57 | +def wag(speed): |
| 58 | + tail.throttle = speed |
| 59 | + time.sleep(0.1) |
| 60 | + tail.throttle = 0.0 |
| 61 | + time.sleep(0.25) |
| 62 | + |
| 63 | + |
| 64 | +def wag_for(seconds): |
| 65 | + target_time = time.monotonic() + seconds |
| 66 | + wag_throttle = 1.0 |
| 67 | + while time.monotonic() < target_time: |
| 68 | + wag(wag_throttle) |
| 69 | + wag_throttle *= -1 |
| 70 | + |
| 71 | + |
| 72 | +def forward(servo_or_servos, speed): |
| 73 | + if isinstance(servo_or_servos, list): |
| 74 | + for servo in servo_or_servos: |
| 75 | + servo.throttle = speed * direction_values[servo] |
| 76 | + else: |
| 77 | + servo_or_servos.throttle = speed * direction_values[servo_or_servos] |
| 78 | + |
| 79 | + |
| 80 | +def reverse(servo_or_servos, speed): |
| 81 | + if isinstance(servo_or_servos, list): |
| 82 | + for servo in servo_or_servos: |
| 83 | + servo.throttle = speed * -1 * direction_values[servo] |
| 84 | + else: |
| 85 | + servo_or_servos.throttle = speed * -1 * direction_values[servo_or_servos] |
| 86 | + |
| 87 | + |
| 88 | +def stop(servo_or_servos): |
| 89 | + if isinstance(servo_or_servos, list): |
| 90 | + for servo in servo_or_servos: |
| 91 | + servo.throttle = 0 |
| 92 | + else: |
| 93 | + servo_or_servos.throttle = 0 |
| 94 | + |
| 95 | + |
| 96 | +def rotate_clockwise(speed): |
| 97 | + forward(left_legs, speed) |
| 98 | + reverse(right_legs, speed) |
| 99 | + |
| 100 | + |
| 101 | +def rotate_counterclockwise(speed): |
| 102 | + forward(right_legs, speed) |
| 103 | + reverse(left_legs, speed) |
| 104 | + |
| 105 | + |
| 106 | +def crawl_forward(speed): |
| 107 | + forward(all_legs, speed) |
| 108 | + |
| 109 | + |
| 110 | +def crawl_backward(speed): |
| 111 | + reverse(all_legs, speed) |
| 112 | + |
| 113 | + |
| 114 | +def turtle(): |
| 115 | + stop([rear_right, rear_left]) |
| 116 | + stop(rear_left) |
| 117 | + forward(front_right, 0.5) |
| 118 | + forward(front_left, 0.5) |
| 119 | + |
| 120 | + |
| 121 | +def snake_step(): |
| 122 | + stop(all_legs) |
| 123 | + forward(right_legs, 0.5) |
| 124 | + time.sleep(1.0) |
| 125 | + stop(right_legs) |
| 126 | + forward(left_legs, 0.5) |
| 127 | + time.sleep(1.0) |
| 128 | + stop(left_legs) |
| 129 | + |
| 130 | + |
| 131 | +init() |
| 132 | + |
| 133 | +def demo1(): |
| 134 | + crawl_forward(0.5) |
| 135 | + wag_for(5.0) |
| 136 | + rotate_clockwise(0.25) |
| 137 | + wag_for(3.0) |
| 138 | + crawl_backward(0.5) |
| 139 | + wag_for(2.0) |
| 140 | + rotate_counterclockwise(0.25) |
| 141 | + wag_for(3.0) |
| 142 | + crawl_forward(0.5) |
| 143 | + wag_for(5.0) |
| 144 | + stop(all_legs) |
| 145 | + |
| 146 | +demo1() |
0 commit comments