bitsy-ai / rpi-object-tracking

Object tracking tutorial using TensorFlow / TensorFlow Lite, Raspberry Pi, Pi Camera, and a Pimoroni Pan-Tilt Hat.
https://medium.com/@grepLeigh/real-time-object-tracking-with-tensorflow-raspberry-pi-and-pan-tilt-hat-2aeaef47e134
MIT License
178 stars 70 forks source link

Investigate use of PCA9685 servo driver in place of Pimoroni custom servo driver #23

Closed TCIII closed 3 years ago

TCIII commented 4 years ago

Description

Trying to purchase the designated hardware, however Pimoroni Pan/Tilt HAT is out of stock and no ETA. Also to be able to run the Rpi 4B+ without it throttling back, it takes a good size heat sink and fan that the Pimoroni Servo Driver HAT will physically interfere with.

What I Did

Investigated alternate servo drivers. The Pimoroni Pan/Tilt HAT uses a custom, proprietary IC chip to generate the servo PWM signals unlike most other servo drivers modules/HATs that use the PCA9685 servo driver IC. Pimoroni originally used the Adafruit PCA9685 library for the pantilthat function, before switching to the proprietary IC chip servo driver, as can be found here: https://github.com/RogueM/PanTiltFacetracker

The PCA9685 will also allow the use of bigger servos, in place of the Pimoroni Servo Driver HAT/Pan-Tilt Gimbal, to drive bigger gimbals that may include other equipment than just the pi V2 camera!

Recommend that you create a branch that allows the use of the PCA9865 servo driver board and Adafruit PCA9685 library in place of the Pimoroni proprietary IC servo driver and library. I believe that this will require minor modifications to the rpi-deep-pantilt/control/manager.py and hardware_test.py code.

Regards, Thomas Coyle System Engineer

TCIII commented 4 years ago

After reviewing the differences between the servo commands available with the PCA9685 servo controller as compared to those available with the Pimoroni custom IC servo controller, it is not going to be feasible to attempt to convert the Pimoroni servo controller library to the Adafruit PCA9685 library.

Fortunately I was able to get the Pimoroni Pan/Tilt HAT from Adafruit and the Pan/Tilt Servo Assembly from Amazon prime. I also purchased serveral Rpi GPIO bus extenders to be able to mount the Pimoroni Pan/Tilt HAT on the top of my fan cooled Rpi 4B+ case. Being able to run the Rpi 4B+ without it throttling back due to overheating will definitely improve the projects tracking performance.

Also I plan to just pull the two servo control PWM signals and grounds off of the Pimoroni servo controller and power the servos separately from a 5vdc source. Once I get the project working correctly I plan to build a bigger Pan/Tilt Servo Assembly, but will have to adjust the PID values to comply with the bigger servos' dynamic performance.

Regards, Thomas Coyle System Engineer

TCIII commented 3 years ago

@arminf' Until Leigh updates her code to allow the use of the PCA9685 servo driver module, I recommend purchasing a Pimoroni servo controller HAT without the gimbals if you want to drive bigger servos. Then all you have to do is take the PWM signal and the GND line for each servo from the Pimoroni HAT to provide the control signal/common ground and add a separate 5 vdc power supply to the servo PWR and GND wires. I think that this is a good interim solution instead of trying to find and replace all of the Pimoroni servo commands embedded in Leigh's code.

TCIII commented 3 years ago

@arminf https://github.com/arminf' Until Leigh updates her code to allow the use of the PCA9685 servo driver module, I recommend purchasing a Pimoroni servo controller HAT without the gimbals if you want to drive bigger servos. Then all you have to do is take the PWM signal and the GND line for each servo from the Pimoroni HAT to provide the control signal/common ground and add a separate 5 vdc power supply to the servo PWR and GND wires. I think that this is a good interim solution instead of trying to find and replace all of the Pimoroni servo commands embedded in Leigh's code.

Regards, TCIII

On Wed, Aug 12, 2020 at 11:48 AM arminf notifications@github.com wrote:

I want to use a regular PCA9685 with my custom pan tilt head. Any hints on where I have to change what?

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/leigh-johnson/rpi-deep-pantilt/issues/23#issuecomment-672955467, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAJO2HDHWB4RIALUZ777FWLSAK2UBANCNFSM4LRDOZ5Q .

kindofausername commented 3 years ago

@TCIII Thank you. I just found some code that I wrote for Adrian Rosebrock's PanTilt Tracker to make it work with my PCA9685 and custom servos. It is very quick and dirty but it seems to work. I still have to figure out the correct PID values.

I made the changes in the pip installation directory: /home/pi/.local/lib/python3.7/site-packages/rpi_deep_pantilt/control

hardware_test.py

# ORI import pantilthat
from rpi_deep_pantilt.control import myCamMount as cm
servoChannelTilt = 0
servoChannelBase = 3

# ORI pantilthat.pan(a)
# ORI pantilthat.tilt(a)
cm.moveToPosition(servoChannelBase, a, "pan")
cm.moveToPosition(servoChannelTilt, a, "tilt")

manager.py

import time

# ORI import pantilthat as pth
from rpi_deep_pantilt.control import myCamMount as cm
servoChannelTilt = 0
servoChannelBase = 3

# ORI pth.servo_enable(1, False)
# ORI pth.servo_enable(2, False)
setHome_y_x()

def setHome_y_x():
    # set servos to 0, 0 coordinates and disable them
    cm.moveToPosition(servoChannelBase, 0, "pan")
    cm.moveToPosition(servoChannelTilt, 0, "tilt")
    time.sleep(1)
    cm.resetServo(servoChannelBase)
    cm.resetServo(servoChannelTilt)

# Inside def set_servos(pan, tilt):
# ORI pth.pan(pan_angle)
cm.moveToPosition(servoChannelBase, pan_angle, "pan")

# ORI pth.tilt(tilt_angle)
cm.moveToPosition(servoChannelTilt, tilt_angle, "tilt")

# Inside def pantilt_process_manager:**
# ORI pth.servo_enable(1, True)
# ORI pth.servo_enable(2, True)

And I added a new file inside the pip control folder: myCamMount.py


import Adafruit_PCA9685
import time
global pwm

pwmHz = 50

if pwmHz == 50:
    print("Servos running on 50 Hz")
    # pan settings
    convertTominRangePan = 90
    convertTomaxRangePan = -90
    originalMinPan = 500
    originalMaxPan = 250
    # tilt settings
    convertTominRangeTilt = 90
    convertTomaxRangeTilt = -90
    originalMinTilt = 270
    originalMaxTilt = 550

pwm = Adafruit_PCA9685.PCA9685(address=0x40)
pwm.set_pwm_freq(pwmHz)

def translate(toPosition, convertTominRange, convertTomaxRange, originalMin, originalMax):
    leftSpan = convertTomaxRange - convertTominRange
    rightSpan = originalMax - originalMin
    valueScaled = float(toPosition - convertTominRange) / float(leftSpan)
    return int(originalMin + (valueScaled * rightSpan))

def moveToPosition(channel, position, panOrTilt):
    if panOrTilt == "pan":
        pwm.set_pwm(channel, 0, translate(position, convertTominRangePan, convertTomaxRangePan, originalMinPan, originalMaxPan))
    if panOrTilt == "tilt":
        pwm.set_pwm(channel, 0, translate(position, convertTominRangeTilt, convertTomaxRangeTilt, originalMinTilt, originalMaxTilt))

def resetServo(channel):
    pwm.set_pwm(channel, 0, 0)
kindofausername commented 3 years ago

@arminf https://github.com/arminf'

This is not my repository ;-). Mine is: https://github.com/arminf82