Things used in this project

Hardware components:
Pack pro mobile lgnchugrkz
Walabot
×1
Pi 3 02
Raspberry Pi 3 Model B
×1
Adafruit 16 channel PWM controller
×1
Software apps and online services:
Dp image kit 02
Amazon Alexa Alexa Skills Kit
Ha 2up iot
Amazon Web Services AWS IoT
Screen%20shot%202015 07 20%20at%206.10.26%20pm
Amazon Web Services AWS Lambda

Schematics

Servo Controller Schematic
How the servo controller board connects to Raspberry Pi T cobbler board
Servo schematic m7jo1iphlx

Code

Added Target Tracking To Walabot Sensor Demo Python CodePython
used to track the nearest target detected by moving azimuth elevation mount
from __future__ import print_function # WalabotAPI works on both Python 2 an 3.
from __future__ import division
from sys import platform
from os import system
from imp import load_source
from os.path import join
# merging stuff learned from Medicine Reminder project
#import paho.mqtt.client as mqtt
import json, time, sys, ssl
import logging, logging.handlers
#import RPi.GPIO as GPIO #GPIO is not exactly what we want for I2C
# Import the PCA9685 module.
import Adafruit_PCA9685
import math

if platform == 'win32':
	modulePath = join('C:/', 'Program Files', 'Walabot', 'WalabotSDK',
		'python', 'WalabotAPI.py')
elif platform.startswith('linux'):
    modulePath = join('/usr', 'share', 'walabot', 'python', 'WalabotAPI.py')     

wlbt = load_source('WalabotAPI', modulePath)
wlbt.Init()

def PrintSensorTargets(targets):
    system('cls' if platform == 'win32' else 'clear')
    if targets:
        for i, target in enumerate(targets):
            print('Target #{}:\nx: {}\ny: {}\nz: {}\namplitude: {}\n'.format(
                i + 1, target.xPosCm, target.yPosCm, target.zPosCm,
                target.amplitude))
    else:
        print('No Target Detected')

def RobotSensorApp():
    deadband = math.pi * (6/180)
    # Initialise the PCA9685 using the default address (0x40).
    pwm = Adafruit_PCA9685.PCA9685()
    # Configure min and max servo pulse lengths
    el_servo_min = 350 #320  #25 degrees inclined down
    el_servo_max = 420  #25 degrees inclined up
    el_servo_ctr = 370 #level
    el_servo_cmd = el_servo_ctr #start from center position
    az_servo_min = 270 #ahead
    az_servo_max = 455 #45 degrees to the right
    az_servo_ctr = 365 #45 degrees to the left
    az_servo_cmd = az_servo_ctr #start from center position
    
    # Set frequency to 60hz, good for servos.
    pwm.set_pwm_freq(60)
    pwm.set_pwm(0, 0, el_servo_ctr) #elevation
    pwm.set_pwm(1, 0, az_servo_ctr) #azimuth
       
    # wlbt.SetArenaR - input parameters
    minInCm, maxInCm, resInCm = 30, 200, 3
    # wlbt.SetArenaTheta - input parameters
    minIndegrees, maxIndegrees, resIndegrees = -15, 15, 5
    # wlbt.SetArenaPhi - input parameters
    minPhiInDegrees, maxPhiInDegrees, resPhiInDegrees = -60, 60, 5
    # Set MTI mode
    mtiMode = False
    # Configure Walabot database install location (for windows)
    wlbt.SetSettingsFolder()
    # 1) Connect : Establish communication with walabot.
    wlbt.ConnectAny()
    # 2) Configure: Set scan profile and arena
    # Set Profile - to Sensor.
    wlbt.SetProfile(wlbt.PROF_SENSOR)
    # Setup arena - specify it by Cartesian coordinates.
    wlbt.SetArenaR(minInCm, maxInCm, resInCm)
    # Sets polar range and resolution of arena (parameters in degrees).
    wlbt.SetArenaTheta(minIndegrees, maxIndegrees, resIndegrees)
    # Sets azimuth range and resolution of arena.(parameters in degrees).
    wlbt.SetArenaPhi(minPhiInDegrees, maxPhiInDegrees, resPhiInDegrees)
    # Moving Target Identification: standard dynamic-imaging filter
    filterType = wlbt.FILTER_TYPE_MTI if mtiMode else wlbt.FILTER_TYPE_NONE
    wlbt.SetDynamicImageFilter(filterType)
    # 3) Start: Start the system in preparation for scanning.
    wlbt.Start()
    if not mtiMode: # if MTI mode is not set - start calibrartion
        # calibrates scanning to ignore or reduce the signals
        wlbt.StartCalibration()
        while wlbt.GetStatus()[0] == wlbt.STATUS_CALIBRATING:
            wlbt.Trigger()
    while True:
        appStatus, calibrationProcess = wlbt.GetStatus()
        # 5) Trigger: Scan(sense) according to profile and record signals
        # to be available for processing and retrieval.
        wlbt.Trigger()
        # 6) Get action: retrieve the last completed triggered recording
        targets = wlbt.GetSensorTargets()
        rasterImage, _, _, sliceDepth, power = wlbt.GetRawImageSlice()
        # PrintSensorTargets(targets)
        #PrintSensorTargets(targets)
        # Move servos
        dist_sq = 10000000 #infinity
        x_ang = 0
        y_ang = 0
        if targets:
            for i, target in enumerate(targets):
                dist_calc_sq = target.xPosCm * target.xPosCm
                dist_calc_sq += target.yPosCm * target.yPosCm
                dist_calc_sq += target.zPosCm * target.zPosCm
                if dist_calc_sq <= dist_sq:
                    dist_sq = dist_calc_sq
                    x_ang = math.atan(target.xPosCm / target.zPosCm)
                    y_ang = math.atan(target.yPosCm / target.zPosCm)

        #move if not against a travel limit
        if x_ang > deadband:
           if az_servo_cmd < az_servo_max:
                   az_servo_cmd+=10
        if x_ang < -deadband:
           if az_servo_cmd > az_servo_min:
                   az_servo_cmd-=10
        if y_ang > deadband:
           if el_servo_cmd < el_servo_max:
                   el_servo_cmd+=10
        if y_ang < -deadband:
           if el_servo_cmd > el_servo_min:
                   el_servo_cmd-=10
        #print(az_servo_cmd)            
        pwm.set_pwm(0, 0, el_servo_cmd) #elevation
        pwm.set_pwm(1, 0, az_servo_cmd) #azimuth
    
    # 7) Stop and Disconnect.
    wlbt.Stop()
    wlbt.Disconnect()
    print('Terminate successfully')

if __name__ == '__main__':
    RobotSensorApp()
Azimuth Elevation Servo TestPython
# Simple demo of of the PCA9685 PWM servo/LED controller library.
# This will move channel 0 from min to max position repeatedly.
# Author: Tony DiCola
# License: Public Domain
from __future__ import division
import time

# Import the PCA9685 module.
import Adafruit_PCA9685


# Uncomment to enable debug output.
#import logging
#logging.basicConfig(level=logging.DEBUG)

# Initialise the PCA9685 using the default address (0x40).
pwm = Adafruit_PCA9685.PCA9685()

# Alternatively specify a different address and/or bus:
#pwm = Adafruit_PCA9685.PCA9685(address=0x41, busnum=2)

# Configure min and max servo pulse lengths
servo_min = 375  #TWM was 150  Min pulse length out of 4096
servo_max = 400  #TWM was 600 Max pulse length out of 4096
az_servo_min = 350
az_servo_max = 450

# Helper function to make setting a servo pulse width simpler.
def set_servo_pulse(channel, pulse):
    pulse_length = 1000000    # 1,000,000 us per second
    pulse_length //= 60       # 60 Hz
    print('{0}us per period'.format(pulse_length))
    pulse_length //= 4096     # 12 bits of resolution
    print('{0}us per bit'.format(pulse_length))
    pulse *= 1000
    pulse //= pulse_length
    pwm.set_pwm(channel, 0, pulse)

# Set frequency to 60hz, good for servos.
pwm.set_pwm_freq(60)

print('Moving servo on channel 0, press Ctrl-C to quit...')
while True:
    # Move servo on channel O between extremes.
    pwm.set_pwm(0, 0, servo_min) #elevation
    pwm.set_pwm(1, 0, az_servo_min) #azimuth
    time.sleep(5)
    pwm.set_pwm(0, 0, servo_max)
    pwm.set_pwm(1, 0, az_servo_max)
    time.sleep(5)
Improved code for smooth motion of azimuth elevation mountPython
from __future__ import print_function # WalabotAPI works on both Python 2 an 3.
from __future__ import division
from sys import platform
from os import system
from imp import load_source
from os.path import join
# merging stuff learned from Medicine Reminder project
#import paho.mqtt.client as mqtt
import json, time, sys, ssl
import logging, logging.handlers
#import RPi.GPIO as GPIO #GPIO is not exactly what we want for I2C
# Import the PCA9685 module.
import Adafruit_PCA9685
import math

if platform == 'win32':
	modulePath = join('C:/', 'Program Files', 'Walabot', 'WalabotSDK',
		'python', 'WalabotAPI.py')
elif platform.startswith('linux'):
    modulePath = join('/usr', 'share', 'walabot', 'python', 'WalabotAPI.py')     

wlbt = load_source('WalabotAPI', modulePath)
wlbt.Init()

def PrintSensorTargets(targets):
    system('cls' if platform == 'win32' else 'clear')
    if targets:
        for i, target in enumerate(targets):
            print('Target #{}:\nx: {}\ny: {}\nz: {}\namplitude: {}\n'.format(
                i + 1, target.xPosCm, target.yPosCm, target.zPosCm,
                target.amplitude))
    else:
        print('No Target Detected')

def RobotSensorApp():
    deadband = math.pi * (6/180)
    # Initialise the PCA9685 using the default address (0x40).
    pwm = Adafruit_PCA9685.PCA9685()
    # Configure min and max servo pulse lengths
    el_servo_min = 350 #320  #25 degrees inclined down
    el_servo_max = 420  #25 degrees inclined up
    el_servo_ctr = 370 #level
    el_servo_cmd = el_servo_ctr #start from center position
    az_servo_min = 270 #ahead
    az_servo_max = 455 #45 degrees to the right
    az_servo_ctr = 365 #45 degrees to the left
    az_servo_cmd = az_servo_ctr #start from center position
    
    # Set frequency to 60hz, good for servos.
    pwm.set_pwm_freq(60)
    pwm.set_pwm(0, 0, el_servo_ctr) #elevation
    pwm.set_pwm(1, 0, az_servo_ctr) #azimuth
       
    # wlbt.SetArenaR - input parameters
    minInCm, maxInCm, resInCm = 30, 200, 3
    # wlbt.SetArenaTheta - input parameters
    minIndegrees, maxIndegrees, resIndegrees = -15, 15, 5
    # wlbt.SetArenaPhi - input parameters
    minPhiInDegrees, maxPhiInDegrees, resPhiInDegrees = -60, 60, 5
    # Set MTI mode
    mtiMode = False
    # Configure Walabot database install location (for windows)
    wlbt.SetSettingsFolder()
    # 1) Connect : Establish communication with walabot.
    wlbt.ConnectAny()
    # 2) Configure: Set scan profile and arena
    # Set Profile - to Sensor.
    wlbt.SetProfile(wlbt.PROF_SENSOR)
    # Setup arena - specify it by Cartesian coordinates.
    wlbt.SetArenaR(minInCm, maxInCm, resInCm)
    # Sets polar range and resolution of arena (parameters in degrees).
    wlbt.SetArenaTheta(minIndegrees, maxIndegrees, resIndegrees)
    # Sets azimuth range and resolution of arena.(parameters in degrees).
    wlbt.SetArenaPhi(minPhiInDegrees, maxPhiInDegrees, resPhiInDegrees)
    # Moving Target Identification: standard dynamic-imaging filter
    filterType = wlbt.FILTER_TYPE_MTI if mtiMode else wlbt.FILTER_TYPE_NONE
    wlbt.SetDynamicImageFilter(filterType)
    # 3) Start: Start the system in preparation for scanning.
    wlbt.Start()
    if not mtiMode: # if MTI mode is not set - start calibrartion
        # calibrates scanning to ignore or reduce the signals
        wlbt.StartCalibration()
        while wlbt.GetStatus()[0] == wlbt.STATUS_CALIBRATING:
            wlbt.Trigger()
        x_ang = 0
        y_ang = 0
    while True:
        appStatus, calibrationProcess = wlbt.GetStatus()
        # 5) Trigger: Scan(sense) according to profile and record signals
        # to be available for processing and retrieval.
        wlbt.Trigger()

        for i in range(20):
                #move if not against a travel limit
                if x_ang > deadband:
                   if az_servo_cmd < az_servo_max:
                           az_servo_cmd+=1
                if x_ang < -deadband:
                   if az_servo_cmd > az_servo_min:
                           az_servo_cmd-=1
                if y_ang > deadband:
                   if el_servo_cmd < el_servo_max:
                           el_servo_cmd+=1
                if y_ang < -deadband:
                   if el_servo_cmd > el_servo_min:
                           el_servo_cmd-=1
                #print(az_servo_cmd)            
                pwm.set_pwm(0, 0, el_servo_cmd) #elevation
                pwm.set_pwm(1, 0, az_servo_cmd) #azimuth
                time.sleep(0.1)

        
        # 6) Get action: retrieve the last completed triggered recording
        targets = wlbt.GetSensorTargets()
        # rasterImage, _, _, sliceDepth, power = wlbt.GetRawImageSlice()
        # PrintSensorTargets(targets)
        #PrintSensorTargets(targets)
        # Move servos
        dist_sq = 10000000 #infinity
        x_ang = 0
        y_ang = 0
        if targets:
            for i, target in enumerate(targets):
                dist_calc_sq = target.xPosCm * target.xPosCm
                dist_calc_sq += target.yPosCm * target.yPosCm
                dist_calc_sq += target.zPosCm * target.zPosCm
                if dist_calc_sq <= dist_sq:
                    dist_sq = dist_calc_sq
                    x_ang = math.atan(target.xPosCm / target.zPosCm)
                    y_ang = math.atan(target.yPosCm / target.zPosCm)


    
    # 7) Stop and Disconnect.
    wlbt.Stop()
    wlbt.Disconnect()
    print('Terminate successfully')

if __name__ == '__main__':
    RobotSensorApp()

Credits

20130301 103720 1
Tom Minnich
11 projects • 41 followers
Embedded software guy for a long time
Contact

Replications

Did you replicate this project? Share it!

I made one

Love this project? Think it could be improved? Tell us what you think!

Give feedback

Comments

Add projectSign up / Login