Skip to content

Instantly share code, notes, and snippets.

@erm3nda
Forked from clungzta/raspberry_pi_car.py
Created May 19, 2018 03:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save erm3nda/551bd85808692959a4dddbdb008e2a15 to your computer and use it in GitHub Desktop.
Save erm3nda/551bd85808692959a4dddbdb008e2a15 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.
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)
#!/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