Last active
March 27, 2024 23:04
-
-
Save clungzta/2bb5e49837078a558ca6382f885a98ba to your computer and use it in GitHub Desktop.
Very Simple Car Driver using a Raspberry Pi 3. Cytron MDD10 Hat controls the motor (Motor 1 port). PWM servo (on GPIO18) controls the steering.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import RPi.GPIO as GPIO | |
import time | |
GPIO.setwarnings(False) # enable warning from GPIO | |
GPIO.setmode(GPIO.BCM) # GPIO numbering | |
class RasPiRCCar(): | |
def __init__(self, motor_dir_pin, motor_pwm_pin, steering_pwm_pin, debug=False): | |
self.debug = debug | |
if self.debug: | |
print('Initialising RC Car') | |
self.motor_dir_pin = motor_dir_pin | |
# Init Throttle | |
GPIO.setup(motor_pwm_pin, GPIO.OUT) | |
GPIO.setup(motor_dir_pin, GPIO.OUT) | |
GPIO.setup(steering_pwm_pin, GPIO.OUT) | |
time.sleep(0.01) | |
self.throttle_pwm = GPIO.PWM(motor_pwm_pin, 100) | |
self.steering_pwm = GPIO.PWM(steering_pwm_pin, 100) | |
self.steering_pwm.start(5) | |
def _update_steering(self, angle): | |
# Move the steering servo to angle (in degrees) | |
assert(0.0<=angle<=90.0) | |
offset = 0.05 | |
duty = float(angle+90.0) / 10.0 + offset | |
self.steering_pwm.ChangeDutyCycle(duty) | |
def _update_throttle(self, speed): | |
# Set the pwm duty of the motor Between -100% and 100% | |
is_forward = (speed >= 0) | |
GPIO.output(self.motor_dir_pin, (not is_forward)) | |
self.throttle_pwm.start(int(abs(speed))) | |
def drive(self, speed, angle): | |
if self.debug: | |
print('Speed: {}%, Steering Angle: {}deg'.format(speed,angle)) | |
self._update_throttle(speed) | |
self._update_steering(angle) | |
if __name__ == "__main__": | |
# Pinout | |
# https://halckemy.s3.amazonaws.com/uploads/attachments/246779/pi-pinout-diagram-01_zvOXVJqUBp.png | |
# Servo Example | |
# http://razzpisampler.oreilly.com/ch05.html | |
# Cytron MDD10 Example | |
# https://github.com/CytronTechnologies/Cytron_MDD10_Hat | |
settings = {'motor_dir_pin' : 26, | |
'motor_pwm_pin' : 12, | |
'steering_pwm_pin' : 18, | |
'debug' : True} | |
car = RasPiRCCar(**settings) | |
print('Testing Motors!') | |
while True: | |
for motor_speed in range(0, 100): | |
car.drive(motor_speed, 45.0) | |
time.sleep(0.1) | |
time.sleep(1) | |
for motor_speed in range(0, 100): | |
car.drive(-motor_speed, 45.0) | |
time.sleep(0.1) | |
time.sleep(1) | |
for steering_angle in range(0, 90): | |
car.drive(0.0, steering_angle) | |
time.sleep(0.01) | |
for steering_angle in range(0, 90): | |
car.drive(0.0, 90-steering_angle) | |
time.sleep(0.01) | |
car.drive(0, steering_angle) | |
time.sleep(1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
import math | |
import rospy | |
from motor_control import RasPiRCCar | |
from ackermann_msgs.msg import AckermannDriveStamped | |
class ROSCarContoller(): | |
def __init__(self): | |
settings = {'motor_dir_pin': 26, | |
'motor_pwm_pin': 12, | |
'steering_pwm_pin': 18} | |
self.car = RasPiRCCar(**settings) | |
rospy.init_node('car_controller', anonymous=True) | |
rospy.Subscriber("ackermann_cmd", AckermannDriveStamped, self.callback) | |
rospy.spin() | |
def callback(self, data): | |
speed = data.drive.speed | |
angle = math.degrees(data.drive.steering_angle) | |
self.car.drive(speed, angle) | |
if __name__ == '__main__': | |
try: | |
c = ROSCarContoller() | |
except rospy.ROSInterruptException: | |
pass |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment