Monday, 15 February 2016

Controlling servo speed - Joe Tubbritt

For sprint 1, I was tasked with developing code to control two servos, one for pan and one for tilt. As an added feature to the standard code used, I wished to be able to fully control the position of the servo but also able to control the speed at which it would get there. Servo's are notorious for trying to get to the inputted value i.e. duty cycle duration, as fast as possible. They will often become damaged as the gears inside are plastic, and will shear as the servo tries to get to its required position too quickly. To counteract this problem, the addition of a speed control is an important consideration. In terms of a safety aspect, the ability to stop a servo damaging itself is highly useful.

To control the speed of a servo, delays were used in the python code. The value of the delay is determined by the desired time divided by full range (delay=desired time/180). The desired time that was used is 3 seconds. This means that in 3 seconds the servo will go from 0 degrees to 180 degrees in a smooth, controlled motion. Per degree it takes 3/180 = 0.016 seconds or 16 milliseconds. So for a 90 degree movement it takes 1.5 seconds, 45 degrees is 0.75 etc.

The code I wrote to implement the speed control is shown below:

import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD)
GPIO.setwarnings(False)
chan_list = [11,18]
GPIO.setup(chan_list, GPIO.OUT)
pwm1=GPIO.PWM(11,50)
pwm2=GPIO.PWM(18,50)
pwm1.start(6)
pwm2.start(6)
currentPosition1 = 90
currentPosition2 = 90
time_to_move = 3
for i in range(0,180):
    desiredPosition1=input("Pan servo position in degrees? 0-180 ")
    desiredPosition2=input("Tilt servo position in degrees? 0-180 ")
    for i in range (0,180):

        for i in range (0, time_to_move):
            while currentPosition1 < desiredPosition1:
                currentPosition1 = currentPosition1 + 1
                time.sleep(0.016)
                DutyCycle1 = 1./18.*(currentPosition1)+1
                pwm1.ChangeDutyCycle(DutyCycle1)
         
            while currentPosition1 > desiredPosition1:
                currentPosition1 = currentPosition1 - 1
                time.sleep(0.016)
                DutyCycle1 = 1./18.*(currentPosition1)+1
                pwm1.ChangeDutyCycle(DutyCycle1)
         
            else:
                currentPosition1 = currentPosition1

    for i in range (0,180):

        for i in range (0, time_to_move):
            while currentPosition2 < desiredPosition2:
                currentPosition2 = currentPosition2 + 1
                time.sleep(0.016)
                DutyCycle2 = 1./18.*(currentPosition2)+1
                pwm2.ChangeDutyCycle(DutyCycle2)
         
            while currentPosition2 > desiredPosition2:
                currentPosition2 = currentPosition2 - 1
                time.sleep(0.016)
                DutyCycle2 = 1./18.*(currentPosition2)+1
                pwm2.ChangeDutyCycle(DutyCycle2)
         
            else:
                currentPosition2 = currentPosition2

pwm1.stop()
pwm2.stop()
GPIO.cleanup()

Please click on the link below to watch a video of the servo speed control in action!

https://www.youtube.com/watch?v=Y1czrjvv5iw


Joe - Blog Post #2

No comments:

Post a Comment