To implement this work into the real world is is necessary to have a hardware unit (Mobile robot). But as the initial step a antenna unit should be implement with following specifications in the real world.
After the simulation was done the hardware setup was implemented. A raspberry pi 3 controlling board was used as the brain and PCA 9685 servo motor controller and MPU 6050 accelerometer sensor were used as the supporting modules. The pan tilt unit was controlled to meet the following specifications as discussed earlier.
With the above specifications a pan tilt unit was controlled and MG90 servo motors was used initially. The basic model of the pan tilt controlled unit was shown in the following video clip. The code for the pan-tilt unit was embed at the last. For the hardware implementation PYTHON was used as the coding language since it was compatible with the raspberry pi . The servo motors were controlled according to the result gain from the WEEK 1 . The controlling algorithm of the antenna was shown in the Figure 38 block diagram.
Since MG90 servo motors doesn't have enough powerful toque to control the 400mm length antenna probe , MG996R metal gear high toque servo motors [Reference] were used to implement the real pan-tilt unit for the mobile robot. And also the pan-tilt unit structure should meet the polar coordinate system specification to move the antenna in an elliptical path. The pan-tilt which was used for the mobile robot was shown in Figure 39.
Figure 38. Block diagram of the controlling algorithm
Figure 39:Pan Tilt unit for the mobile robot
In here it is clearly shown that the antenna tip follows the elliptical path (The antenna tip follows the moving dot on the screen ) .
In this video the antenna with the sensor wasn't mount to the pan-tilt unit because only to develop the algorithm . Here the pan-tilt unit was stopped as soon as the antenna met the object. But as the future work the antenna will be mounted to the pan-tilt unit and tested.
Code for the Pan-Tilt unit controller (Raspberry Pi3 - Python3)
from __future__ import divisionimport smbusimport mathimport timeimport numpy as npimport matplotlib.pyplot as pltimport pygamefrom threading import Threadimport multiprocessingfrom queue import Queue# Import the PCA9685 module.import Adafruit_PCA9685# Alternatively specify a different address and/or bus:pwm = Adafruit_PCA9685.PCA9685(0x40) # pca9685 I2C Addressbus = smbus.SMBus(1)address = 0x68 #MPU6050 I2C adress# +++++++++++++++++++++++++++ Configurations ++++++++++++++++++++++++++++# Configure min and max servo pulse lengthsservo_min = 250 # Min pulse length out of 4096 ---> 150servo_max = 500# Max pulse length out of 4096 ----> 600x_min_old = -88.97162532327404 #18.82269974138087 x_max_old = 483.97162532327417 #477.17730025861925 y_min_old = 99.99999999999997 #125.00000000000001y_max_old = 329.17730025861925 #354.1423954457447 OldRange_x= (x_max_old-x_min_old)NewRange_x = (servo_max - servo_min)OldRange_y = (y_max_old- y_min_old) NewRange_y = (servo_max- servo_min)coords = 150, 150angle = 70radius1 = 5radius2 =2# ++++++++ mpu6050 configurations +++++++power_mgmt_1 = 0x6bpower_mgmt_2 = 0x6c#+++++++++++++++++ functions for mpu6050 +++++++++++++++++++++def read_byte(adr): return bus.read_byte_data(address, adr)def read_word(adr): high = bus.read_byte_data(address, adr) low = bus.read_byte_data(address, adr+1) val = (high << 8) + low return valdef read_word_2c(adr): val = read_word(adr) if (val >= 0x8000): return -((65535 - val) + 1) else: return valdef norm (): accel_xout = read_word_2c(0x3b) #accel_yout = read_word_2c(0x3d) accel_zout = read_word_2c(0x3f) accel_xout_scaled = (accel_xout / 2048.0) #accel_yout_scaled = accel_yout / 2048.0 accel_zout_scaled = (accel_zout / 2048.0) norm = np.sqrt(np.multiply(accel_xout_scaled,accel_xout_scaled)+np.multiply(accel_zout_scaled,accel_zout_scaled )) if (norm<18): p=0 else: p=1 return p #+++++++++++++++++ functions for pca9685+++++++++++++++++++++# 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)def move_coords(angle, radius1, radius2, coords): #def move_coords(angle, radius1, radius2, coords): theta = math.radians(angle) theta2 = math.radians(angle+20) x=coords[0] + radius1 * math.cos(theta) y=coords[1] + radius2 * math.sin(theta) return x, ydef searching(): coords = 150, 150 angle = 70 radius1 = 5 radius2 =2 speed = 0.1 next_tick = 1000 clock = pygame.time.Clock() while True: p=norm() if (p==0): ticks = pygame.time.get_ticks() if ticks > next_tick: next_tick += speed angle += 1 coords = move_coords(angle, radius1,radius2, coords) x_old =coords[0] y_old =coords[1] NewValue_x = (((x_old- x_min_old) * NewRange_x) / OldRange_x) +servo_min NewValue_y = (((y_old - y_min_old) * NewRange_y) / OldRange_y) + servo_min x= int(round(NewValue_x)) y= int(round(NewValue_y)) #print('x=' , x,'y=' , y ) #print(coords) pwm.set_pwm(0, 0, x) pwm.set_pwm(2, 0, y) else: while True: print('stopped') clock.tick(1000) return #++++++++++++++++++++main loops ++++++++++++++++++++++++++++while True: p=norm() print(p) searching()